Files
firezone/elixir/apps/api/lib/api/gateway/socket.ex
bmanifold ef480e1acd Add routing option for sites (#2610)
Why:

* As sites are created, the default behavior right now is to route
traffic through whichever path is easiest/fastest. This commit adds the
ability to allow the admin to choose a routing policy for a given site.
2023-11-22 19:59:54 +00:00

76 lines
2.4 KiB
Elixir

defmodule API.Gateway.Socket do
use Phoenix.Socket
alias Domain.Gateways
require Logger
require OpenTelemetry.Tracer
## Channels
channel "gateway", API.Gateway.Channel
## Authentication
@impl true
def connect(%{"token" => encrypted_secret} = attrs, socket, connect_info) do
:otel_propagator_text_map.extract(connect_info.trace_context_headers)
OpenTelemetry.Tracer.with_span "gateway.connect" do
%{
user_agent: user_agent,
x_headers: x_headers,
peer_data: peer_data
} = connect_info
real_ip = API.Sockets.real_ip(x_headers, peer_data)
{location_region, location_city, {location_lat, location_lon}} =
API.Sockets.load_balancer_ip_location(x_headers)
attrs =
attrs
|> Map.take(~w[external_id name public_key])
|> Map.put("last_seen_user_agent", user_agent)
|> Map.put("last_seen_remote_ip", real_ip)
|> Map.put("last_seen_remote_ip_location_region", location_region)
|> Map.put("last_seen_remote_ip_location_city", location_city)
|> Map.put("last_seen_remote_ip_location_lat", location_lat)
|> Map.put("last_seen_remote_ip_location_lon", location_lon)
with {:ok, token} <- Gateways.authorize_gateway(encrypted_secret),
{:ok, gateway} <- Gateways.upsert_gateway(token, attrs),
{:ok, gateway_group} <- Gateways.fetch_group_by_id(gateway.group_id) do
OpenTelemetry.Tracer.set_attributes(%{
gateway_id: gateway.id,
account_id: gateway.account_id
})
socket =
socket
|> assign(:gateway, gateway)
|> assign(:gateway_group, gateway_group)
|> assign(:opentelemetry_span_ctx, OpenTelemetry.Tracer.current_span_ctx())
|> assign(:opentelemetry_ctx, OpenTelemetry.Ctx.get_current())
{:ok, socket}
else
{:error, :invalid_token} ->
OpenTelemetry.Tracer.set_status(:error, "invalid_token")
{:error, :invalid_token}
{:error, reason} ->
OpenTelemetry.Tracer.set_status(:error, inspect(reason))
Logger.debug("Error connecting gateway websocket: #{inspect(reason)}")
{:error, reason}
end
end
end
def connect(_params, _socket, _connect_info) do
{:error, :missing_token}
end
@impl true
def id(%Gateways.Gateway{} = gateway), do: "gateway:#{gateway.id}"
def id(socket), do: id(socket.assigns.gateway)
end