feat(relay): support custom turn port (#5208)

Original PR: #5130.

Co-authored-by: Antoine <antoinelabarussias@gmail.com>
This commit is contained in:
Thomas Eizinger
2024-06-05 14:04:17 +10:00
committed by GitHub
parent 4ce2913ab9
commit d27a7a3083
8 changed files with 47 additions and 21 deletions

View File

@@ -16,7 +16,7 @@ defmodule API.Relay.Socket do
OpenTelemetry.Tracer.with_span "relay.connect" do
context = API.Sockets.auth_context(connect_info, :relay_group)
attrs = Map.take(attrs, ~w[ipv4 ipv6 name])
attrs = Map.take(attrs, ~w[ipv4 ipv6 name port])
with {:ok, group, token} <- Relays.authenticate(encoded_token, context),
{:ok, relay} <- Relays.upsert_relay(group, token, attrs, context) do

View File

@@ -462,7 +462,7 @@ impl Firewall {
impl TestRelay {
fn new(local: impl Into<RelaySocket>, span: Span) -> Self {
let local = local.into();
let inner = firezone_relay::Server::new(to_ip_stack(local), OsRng, 49152, 65535);
let inner = firezone_relay::Server::new(to_ip_stack(local), OsRng, 3478, 49152, 65535);
Self {
inner,

View File

@@ -226,6 +226,7 @@ impl StateMachineTest for TunnelTest {
state: firezone_relay::Server::new(
ref_state.relay.ip_stack,
rand::rngs::StdRng::seed_from_u64(ref_state.relay.state),
3478,
49152,
65535,
),

View File

@@ -59,6 +59,7 @@ impl LoginUrl {
Some(device_name),
None,
None,
None,
)?;
Ok(LoginUrl {
@@ -88,6 +89,7 @@ impl LoginUrl {
Some(device_name),
None,
None,
None,
)?;
Ok(LoginUrl {
@@ -100,6 +102,7 @@ impl LoginUrl {
url: impl TryInto<Url, Error = E>,
firezone_token: &SecretString,
device_name: Option<String>,
listen_port: u16,
ipv4_address: Option<Ipv4Addr>,
ipv6_address: Option<Ipv6Addr>,
) -> std::result::Result<Self, LoginUrlError<E>> {
@@ -110,6 +113,7 @@ impl LoginUrl {
None,
None,
device_name,
Some(listen_port),
ipv4_address,
ipv6_address,
)?;
@@ -176,6 +180,7 @@ fn get_websocket_path<E>(
public_key: Option<[u8; 32]>,
external_id: Option<String>,
name: Option<String>,
port: Option<u16>,
ipv4_address: Option<Ipv4Addr>,
ipv6_address: Option<Ipv6Addr>,
) -> std::result::Result<Url, LoginUrlError<E>> {
@@ -208,8 +213,11 @@ fn get_websocket_path<E>(
if let Some(ipv4_address) = ipv4_address {
query_pairs.append_pair("ipv4", &ipv4_address.to_string());
}
if let Some(ipv4_address) = ipv6_address {
query_pairs.append_pair("ipv6", &ipv4_address.to_string());
if let Some(ipv6_address) = ipv6_address {
query_pairs.append_pair("ipv6", &ipv6_address.to_string());
}
if let Some(port) = port {
query_pairs.append_pair("port", &port.to_string());
}
}

View File

@@ -44,8 +44,8 @@ firezone-relay --help
### Ports
The relay listens on port `3478`. This is the standard port for STUN/TURN and
not configurable. Additionally, the relay needs to have access to the port range
By default, the relay listens on port `3478`. This is the standard port for
STUN/TURN. Additionally, the relay needs to have access to the port range
`49152` - `65535` for the allocations.
### Portal Connection

View File

@@ -27,8 +27,6 @@ use url::Url;
const STATS_LOG_INTERVAL: Duration = Duration::from_secs(10);
const TURN_PORT: u16 = 3478;
const MAX_PARTITION_TIME: Duration = Duration::from_secs(60 * 15);
#[derive(Parser, Debug)]
@@ -39,6 +37,9 @@ struct Args {
/// The public (i.e. internet-reachable) IPv6 address of the relay server.
#[arg(long, env)]
public_ip6_addr: Option<Ipv6Addr>,
/// The port to listen on for STUN messages.
#[arg(long, env, hide = true, default_value = "3478")]
listen_port: u16,
// See https://www.rfc-editor.org/rfc/rfc8656.html#name-allocations
/// The lowest port used for TURN allocations.
#[arg(long, env, hide = true, default_value = "49152")]
@@ -112,6 +113,7 @@ async fn main() -> Result<()> {
let server = Server::new(
public_addr,
make_rng(args.rng_seed),
args.listen_port,
args.lowest_port,
args.highest_port,
);
@@ -130,6 +132,7 @@ async fn main() -> Result<()> {
args.api_url.clone(),
token,
args.name.clone(),
args.listen_port,
args.public_ip4_addr,
args.public_ip6_addr,
)?;
@@ -153,7 +156,7 @@ async fn main() -> Result<()> {
let mut eventloop = Eventloop::new(server, channel, public_addr, last_heartbeat_sent)?;
tracing::info!(target: "relay", "Listening for incoming traffic on UDP port {TURN_PORT}");
tracing::info!(target: "relay", "Listening for incoming traffic on UDP port {0}", args.listen_port);
future::poll_fn(|cx| eventloop.poll(cx))
.await
@@ -323,16 +326,22 @@ where
if public_address.as_v4().is_some() {
sockets
.bind(TURN_PORT, AddressFamily::V4)
.bind(server.listen_port(), AddressFamily::V4)
.with_context(|| {
format!("Failed to bind to port {TURN_PORT} on IPv4 interfaces")
format!(
"Failed to bind to port {0} on IPv4 interfaces",
server.listen_port()
)
})?;
}
if public_address.as_v6().is_some() {
sockets
.bind(TURN_PORT, AddressFamily::V6)
.bind(server.listen_port(), AddressFamily::V6)
.with_context(|| {
format!("Failed to bind to port {TURN_PORT} on IPv6 interfaces")
format!(
"Failed to bind to port {0} on IPv6 interfaces",
server.listen_port()
)
})?;
}
@@ -360,10 +369,11 @@ where
if let Some(next_command) = self.server.next_command() {
match next_command {
Command::SendMessage { payload, recipient } => {
if let Err(e) =
self.sockets
.try_send(TURN_PORT, recipient.into_socket(), &payload)
{
if let Err(e) = self.sockets.try_send(
self.server.listen_port(),
recipient.into_socket(),
&payload,
) {
tracing::warn!(target: "relay", %recipient, "Failed to send message: {e}");
}
}
@@ -416,10 +426,10 @@ where
match self.sockets.poll_recv_from(payload, cx) {
Poll::Ready(Ok(sockets::Received {
port: TURN_PORT, // Packets coming in on the TURN port are from clients.
port, // Packets coming in on the TURN port are from clients.
from,
packet,
})) => {
})) if port == self.server.listen_port() => {
if let Some((port, peer)) = self.server.handle_client_input(
packet,
ClientSocket::new(from),
@@ -456,7 +466,7 @@ where
);
if let Err(e) = self.sockets.try_send(
TURN_PORT, // Packets coming in from peers always go out on the TURN port
self.server.listen_port(), // Packets coming in from peers always go out on the TURN port
client.into_socket(),
&self.buffer[..total_length],
) {

View File

@@ -60,6 +60,7 @@ pub struct Server<R> {
channel_and_client_by_port_and_peer:
HashMap<(AllocationPort, PeerSocket), (ClientSocket, ChannelNumber)>,
listen_port: u16,
lowest_port: u16,
highest_port: u16,
@@ -154,6 +155,7 @@ where
pub fn new(
public_address: impl Into<IpStack>,
mut rng: R,
listen_port: u16,
lowest_port: u16,
highest_port: u16,
) -> Self {
@@ -181,6 +183,7 @@ where
public_address: public_address.into(),
allocations: Default::default(),
clients_by_allocation: Default::default(),
listen_port,
lowest_port,
highest_port,
channels_by_client_and_number: Default::default(),
@@ -201,6 +204,10 @@ where
&self.auth_secret
}
pub fn listen_port(&self) -> u16 {
self.listen_port
}
/// Registers a new, valid nonce.
///
/// Each nonce is valid for 10 requests.

View File

@@ -696,7 +696,7 @@ struct TestServer {
impl TestServer {
fn new(relay_public_addr: impl Into<IpStack>) -> Self {
Self {
server: Server::new(relay_public_addr, StepRng::new(0, 0), 49152, 65535),
server: Server::new(relay_public_addr, StepRng::new(0, 0), 3478, 49152, 65535),
}
}