Merge pull request #3 from peachcloud/rocket

Initial Working Rocket Server
This commit is contained in:
Max Fowler 2021-04-30 13:20:23 +02:00 committed by GitHub
commit fd2a0fbd92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 943 additions and 420 deletions

1257
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
[package] [package]
name = "peach-dyndns-host" name = "peach-dyndns-host"
version = "0.1.0" version = "0.1.0"
authors = ["Michael Williams <michael.williams@enspiral.com>"] authors = ["Michael Williams <michael.williams@enspiral.com>", "Max Fowler <notplants@mfowler.info>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
@ -9,7 +9,6 @@ clap-log-flag = "0.2"
clap-verbosity-flag = "0.2" clap-verbosity-flag = "0.2"
log = "0.4" log = "0.4"
futures = "0.3.1" futures = "0.3.1"
hyper = { version = "0.14", features = ["full"] }
nest = "1" nest = "1"
structopt = "0.2" structopt = "0.2"
tokio = { version = "1.5.0", features = ["full"] } tokio = { version = "1.5.0", features = ["full"] }
@ -18,3 +17,6 @@ tokio-tcp = "0.1.4"
tokio-udp = "0.1.4" tokio-udp = "0.1.4"
trust-dns-server = "0.20.2" trust-dns-server = "0.20.2"
trust-dns-client = "0.20.2" trust-dns-client = "0.20.2"
rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "master" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", branch = "master" }
serde = "1.0.125"

View File

@ -1,5 +1,3 @@
use clap_log_flag;
use clap_verbosity_flag;
use structopt::StructOpt; use structopt::StructOpt;
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]

View File

@ -1,26 +1,18 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use futures::{future, Future}; use std::time::Duration;
use futures::future::join_all;
use tokio::net::TcpListener; use tokio::net::TcpListener;
use tokio::net::UdpSocket; use tokio::net::UdpSocket;
use trust_dns_client::rr::rdata::soa::SOA; use trust_dns_client::rr::rdata::soa::SOA;
use trust_dns_client::rr::{LowerName, Name, RData, Record, RecordSet, RecordType, RrKey}; use trust_dns_client::rr::{LowerName, Name, RData, Record, RecordSet, RecordType, RrKey};
use trust_dns_server;
use trust_dns_server::authority::{Catalog, ZoneType}; use trust_dns_server::authority::{Catalog, ZoneType};
use trust_dns_server::server::ServerFuture; use trust_dns_server::server::ServerFuture;
use trust_dns_server::store::in_memory::InMemoryAuthority; use trust_dns_server::store::in_memory::InMemoryAuthority;
static DEFAULT_TCP_REQUEST_TIMEOUT: u64 = 5; static DEFAULT_TCP_REQUEST_TIMEOUT: u64 = 5;
pub async fn server() -> ServerFuture<Catalog> { pub async fn server() -> ServerFuture<Catalog> {
info!("Trust-DNS {} starting", trust_dns_server::version()); info!("Trust-DNS {} starting", trust_dns_server::version());
@ -29,8 +21,12 @@ pub async fn server() -> ServerFuture<Catalog> {
let tcp_request_timeout = Duration::from_secs(DEFAULT_TCP_REQUEST_TIMEOUT); let tcp_request_timeout = Duration::from_secs(DEFAULT_TCP_REQUEST_TIMEOUT);
let sock_addr = SocketAddr::new(ip_addr, listen_port); let sock_addr = SocketAddr::new(ip_addr, listen_port);
let udp_socket = UdpSocket::bind(&sock_addr).await.expect("could not bind udp socket"); let udp_socket = UdpSocket::bind(&sock_addr)
let tcp_listener = TcpListener::bind(&sock_addr).await.expect("could not bind tcp listener"); .await
.expect("could not bind udp socket");
let tcp_listener = TcpListener::bind(&sock_addr)
.await
.expect("could not bind tcp listener");
let mut catalog: Catalog = Catalog::new(); let mut catalog: Catalog = Catalog::new();
@ -80,17 +76,19 @@ pub async fn server() -> ServerFuture<Catalog> {
let dyn_record = Record::from_rdata(dyn_name, dyn_ttl, dyn_rdata); let dyn_record = Record::from_rdata(dyn_name, dyn_ttl, dyn_rdata);
authority.upsert(dyn_record, authority.serial()); authority.upsert(dyn_record, authority.serial());
catalog.upsert(LowerName::new(&authority_name), Box::new(Arc::new(RwLock::new(authority)))); catalog.upsert(
LowerName::new(&authority_name),
Box::new(Arc::new(RwLock::new(authority))),
);
let mut server = ServerFuture::new(catalog); let mut server = ServerFuture::new(catalog);
// load all the listeners // load all the listeners
info!("DNS server listening for UDP on {:?}", udp_socket); info!("DNS server listening for UDP on {:?}", udp_socket);
let udp_future = server.register_socket(udp_socket); server.register_socket(udp_socket);
info!("DNS server listening for TCP on {:?}", tcp_listener); info!("DNS server listening for TCP on {:?}", tcp_listener);
let tcp_future = server server.register_listener(tcp_listener, tcp_request_timeout);
.register_listener(tcp_listener, tcp_request_timeout);
info!("awaiting DNS connections..."); info!("awaiting DNS connections...");
server server

View File

@ -1,22 +1,50 @@
use futures::Future; /*
use hyper::{Body, Request, Response, Server}; *
use std::convert::Infallible; * /register-user (sends an email verification to create a new account)
use hyper::service::{make_service_fn, service_fn}; * /verify (for clicking the link in the email)
* /register-domain (add a new domain and get back the secret for subsequent updating)
* /update-domain (update the IP for the domain, passing the associated secret)
*
*/
use rocket_contrib::json::Json;
use serde::Deserialize;
#[get("/")]
fn index() -> &'static str {
"This is the peach-dyn-dns server."
}
async fn handle_request(_req: Request<Body>) -> Result<Response<Body>, Infallible>{ #[derive(Deserialize, Debug)]
Ok(Response::new(Body::from("Hello, World!"))) struct RegisterDomainPost {
domain: String,
}
#[post("/register-domain", data = "<data>")]
fn register_domain(data: Json<RegisterDomainPost>) -> &'static str {
info!("++ post request to register new domain: {:?}", data);
"New domain registered" // TODO: return secret
}
#[derive(Deserialize, Debug)]
struct UpdateDomainPost {
domain: String,
secret: String,
}
#[post("/update-domain", data = "<data>")]
fn update_domain(data: Json<UpdateDomainPost>) -> &'static str {
info!("++ post request to update domain: {:?}", data);
"Updating domain" // TODO: validate, then do it
} }
pub async fn server() { pub async fn server() {
let address = ([127, 0, 0, 1], 3000).into();
let make_svc = make_service_fn(|_conn| async { let rocket_result= rocket::build()
// service_fn converts our function into a `Service` .mount("/", routes![index, register_domain, update_domain])
Ok::<_, Infallible>(service_fn(handle_request)) .launch()
}); .await;
info!("HTTP server listening for TCP on {:?}", address); if let Err(err) = rocket_result {
error!("++ error launching rocket server: {:?}", err);
Server::bind(&address).serve(make_svc).await; }
} }

View File

@ -1,9 +1,10 @@
#[macro_use] #![feature(proc_macro_hygiene, decl_macro)]
extern crate log;
#[macro_use]
extern crate rocket;
use futures::try_join;
use std::io; use std::io;
use futures::{try_join, future, Future};
use nest::{Error, Store, Value};
use tokio::task; use tokio::task;
mod cli; mod cli;
@ -12,8 +13,7 @@ mod http;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let _args = cli::args().expect("error parsing args");
let args = cli::args().expect("error parsing args");
// create future for dns and http servers // create future for dns and http servers
let dns_future = task::spawn(dns::server()); let dns_future = task::spawn(dns::server());
@ -30,7 +30,7 @@ async fn main() {
); );
error!("server failure: {}", e); error!("server failure: {}", e);
} }
Ok(val) => { Ok(_val) => {
info!("we're stopping for some unexpected reason"); info!("we're stopping for some unexpected reason");
} }
} }