cuprated/rpc/
server.rs
1use std::{
4 net::{IpAddr, SocketAddr},
5 time::Duration,
6};
7
8use anyhow::Error;
9use tokio::net::TcpListener;
10use tower::limit::rate::RateLimitLayer;
11use tower_http::limit::RequestBodyLimitLayer;
12use tracing::{field::display, info, warn};
13
14use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy};
15
16use crate::{config::RpcConfig, rpc::CupratedRpcHandler};
17
18pub fn init_rpc_servers(config: RpcConfig) {
26 for ((enable, addr, request_byte_limit), restricted) in [
27 (
28 (
29 config.unrestricted.enable,
30 config.unrestricted.address,
31 config.unrestricted.request_byte_limit,
32 ),
33 false,
34 ),
35 (
36 (
37 config.restricted.enable,
38 config.restricted.address,
39 config.restricted.request_byte_limit,
40 ),
41 true,
42 ),
43 ] {
44 if !enable {
45 info!(restricted, "Skipping RPC server");
46 continue;
47 }
48
49 if !restricted && !cuprate_helper::net::ip_is_local(addr.ip()) {
50 if config
51 .unrestricted
52 .i_know_what_im_doing_allow_public_unrestricted_rpc
53 {
54 warn!(
55 address = display(addr),
56 "Starting unrestricted RPC on non-local address, this is dangerous!"
57 );
58 } else {
59 panic!("Refusing to start unrestricted RPC on a non-local address ({addr})");
60 }
61 }
62
63 tokio::task::spawn(async move {
64 run_rpc_server(restricted, addr, request_byte_limit)
65 .await
66 .unwrap();
67 });
68 }
69}
70
71async fn run_rpc_server(
75 restricted: bool,
76 address: SocketAddr,
77 request_byte_limit: usize,
78) -> Result<(), Error> {
79 info!(
80 restricted,
81 address = display(&address),
82 "Starting RPC server"
83 );
84
85 let state = RpcHandlerDummy { restricted };
89 let router = RouterBuilder::new().fallback().build().with_state(state);
97
98 let router = if request_byte_limit != 0 {
102 router.layer(RequestBodyLimitLayer::new(request_byte_limit))
103 } else {
104 router
105 };
106
107 let listener = TcpListener::bind(address).await?;
111 axum::serve(listener, router).await?;
112
113 Ok(())
114}