sentry and other misc stuff
This commit is contained in:
		
							parent
							
								
									3d381e017f
								
							
						
					
					
						commit
						eafc9e355c
					
				
					 6 changed files with 893 additions and 38 deletions
				
			
		
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
{
 | 
			
		||||
    "rust-analyzer.check.command": "check"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										895
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										895
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -7,10 +7,9 @@ license = "MIT OR Apache-2.0"
 | 
			
		|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
anyhow = { version = "1.0.71", features = ["backtrace"] }
 | 
			
		||||
async-trait = "0.1.68"
 | 
			
		||||
axum = "0.6.18"
 | 
			
		||||
env_logger = "0.10.0"
 | 
			
		||||
eyre = "0.6.12"
 | 
			
		||||
idna = "0.4.0"
 | 
			
		||||
log = "0.4.19"
 | 
			
		||||
parking_lot = "0.12.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +17,7 @@ quinn = "0.10.1"
 | 
			
		|||
rand = "0.8.5"
 | 
			
		||||
rustls = "0.21.9"
 | 
			
		||||
rustls-pemfile = "1.0.2"
 | 
			
		||||
sentry = { version = "0.34.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] }
 | 
			
		||||
serde = { version = "1.0.164", features = ["derive"] }
 | 
			
		||||
serde_json = "1.0.97"
 | 
			
		||||
thiserror = "1.0.40"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,6 +113,12 @@
 | 
			
		|||
              example = "/path/to/key.pem";
 | 
			
		||||
              description = lib.mdDoc "Path to TLS key to use for quiclime connections.";
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            sentryDsn = mkOption {
 | 
			
		||||
              type = types.str;
 | 
			
		||||
              example = "https://key@sentry.io/42";
 | 
			
		||||
              description = lib.mdDoc "Sentry DSN to use for error reports.";
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -137,6 +143,7 @@
 | 
			
		|||
              QUICLIME_BIND_ADDR_WEB = cfg.controlAddr;
 | 
			
		||||
              QUICLIME_CERT_PATH = cfg.cert;
 | 
			
		||||
              QUICLIME_KEY_PATH = cfg.key;
 | 
			
		||||
              SENTRY_DSN = cfg.sentryDsn;
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
 | 
			
		||||
use std::{convert::Infallible, net::SocketAddr, sync::Arc, time::Duration};
 | 
			
		||||
 | 
			
		||||
use anyhow::{anyhow, Context};
 | 
			
		||||
use eyre::{anyhow, Context, self as anyhow};
 | 
			
		||||
use axum::{
 | 
			
		||||
    http::StatusCode,
 | 
			
		||||
    routing::{get, post},
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +85,7 @@ async fn create_server_config() -> anyhow::Result<ServerConfig> {
 | 
			
		|||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() -> anyhow::Result<()> {
 | 
			
		||||
    let _guard = sentry::init(std::env::var("SENTRY_DSN").ok());
 | 
			
		||||
    env_logger::init();
 | 
			
		||||
    // JUSTIFICATION: this lives until the end of the entire program
 | 
			
		||||
    let endpoint = Box::leak(Box::new(Endpoint::server(
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +104,7 @@ async fn main() -> anyhow::Result<()> {
 | 
			
		|||
        listen_control(endpoint, routing_table),
 | 
			
		||||
        listen_minecraft(routing_table)
 | 
			
		||||
    )?;
 | 
			
		||||
    drop(_guard);
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +184,7 @@ async fn try_handle_quic(
 | 
			
		|||
 | 
			
		||||
async fn handle_quic(connection: Connecting, routing_table: &RoutingTable) {
 | 
			
		||||
    if let Err(e) = try_handle_quic(connection, routing_table).await {
 | 
			
		||||
        sentry::capture_error::<dyn std::error::Error>(e.as_ref());
 | 
			
		||||
        error!("Error handling QUIClime connection: {}", e);
 | 
			
		||||
    };
 | 
			
		||||
    info!("Finished handling QUIClime connection");
 | 
			
		||||
| 
						 | 
				
			
			@ -225,6 +228,9 @@ async fn listen_control(
 | 
			
		|||
        .route(
 | 
			
		||||
            "/stop",
 | 
			
		||||
            post(|| async {
 | 
			
		||||
                endpoint.reject_new_connections();
 | 
			
		||||
                routing_table.broadcast("e4mc relay server stopping!");
 | 
			
		||||
                tokio::time::sleep(Duration::from_secs(1)).await;
 | 
			
		||||
                endpoint.close(0u32.into(), b"e4mc closing");
 | 
			
		||||
            }),
 | 
			
		||||
        );
 | 
			
		||||
| 
						 | 
				
			
			@ -259,11 +265,8 @@ async fn try_handle_minecraft(
 | 
			
		|||
        return politely_disconnect(connection, handshake).await;
 | 
			
		||||
    };
 | 
			
		||||
    handshake.send(&mut send_host).await?;
 | 
			
		||||
    let (mut recv_client, mut send_client) = connection.split();
 | 
			
		||||
    tokio::select! {
 | 
			
		||||
        _ = tokio::io::copy(&mut recv_client, &mut send_host) => (),
 | 
			
		||||
        _ = tokio::io::copy(&mut recv_host, &mut send_client) => ()
 | 
			
		||||
    }
 | 
			
		||||
    let mut conn_host = tokio::io::join(&mut recv_host, &mut send_host);
 | 
			
		||||
    _ = tokio::io::copy_bidirectional(&mut connection, &mut conn_host);
 | 
			
		||||
    _ = connection.shutdown().await;
 | 
			
		||||
    _ = send_host.finish().await;
 | 
			
		||||
    _ = recv_host.stop(0u32.into());
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +326,8 @@ async fn politely_disconnect(
 | 
			
		|||
 | 
			
		||||
async fn handle_minecraft(connection: TcpStream, routing_table: &'static RoutingTable) {
 | 
			
		||||
    if let Err(e) = try_handle_minecraft(connection, routing_table).await {
 | 
			
		||||
        error!("Error handling Minecraft connection: {}", e.backtrace());
 | 
			
		||||
        sentry::capture_error::<dyn std::error::Error>(e.as_ref());
 | 
			
		||||
        error!("Error handling Minecraft connection: {:#}", e);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -340,6 +344,7 @@ async fn listen_minecraft(routing_table: &'static RoutingTable) -> anyhow::Resul
 | 
			
		|||
                tokio::spawn(handle_minecraft(connection, routing_table));
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                sentry::capture_error(&e);
 | 
			
		||||
                error!("Error accepting minecraft connection: {}", e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,9 @@ use std::io::Read;
 | 
			
		|||
 | 
			
		||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
 | 
			
		||||
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use log::error;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
use eyre as anyhow;
 | 
			
		||||
 | 
			
		||||
#[derive(Error, Debug)]
 | 
			
		||||
pub enum ReadError {
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +119,6 @@ async fn read_varint(mut reader: impl AsyncReadExt + Unpin) -> Result<i32, ReadE
 | 
			
		|||
 | 
			
		||||
impl<T: Read> ReadExt for T {}
 | 
			
		||||
 | 
			
		||||
#[async_trait]
 | 
			
		||||
pub trait WriteExt: AsyncWriteExt + Unpin {
 | 
			
		||||
    async fn write_varint(&mut self, mut val: i32) -> std::io::Result<()> {
 | 
			
		||||
        for _ in 0..5 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue