masque_udp_proxy_handler (masque v0.7.0)

View Source

Built-in MASQUE handler that bridges a CONNECT-UDP tunnel to a real UDP flow on the server.

For every accepted tunnel the handler opens a gen_udp socket bound to ephemeral port and a specific family, resolves the target hostname, and relays bytes in both directions:

  • Client-to-target: handle_packet/2 sends the payload to the resolved target on the UDP socket.
  • Target-to-client: {udp, Socket, _, _, Bytes} messages arrive on the session process and are emitted as send actions back through the tunnel.

Configure policy via handler_opts:

  • allow => fun(target()) -> boolean() - gate on host+port.
  • resolver => fun(binary()) -> {ok, inet:ip_address()} | {error, term()} - override the default inet:getaddr/2 resolver.
  • family => inet | inet6 | auto (default auto).
  • socket_opts => [gen_udp:option()] - extra options merged on top of [binary, {active, true}].
  • port => inet:port_number() - bind the local UDP socket to a fixed port. Default 0 (kernel-assigned ephemeral). Useful for firewall rules; conflicts with concurrent tunnels that share a listener.

Summary

Functions

accept(Req)

handle_info(Other, State)

-spec handle_info(term(),
                  #state{socket :: gen_udp:socket(),
                         target_ip :: inet:ip_address(),
                         target_port :: 1..65535}) ->
                     {ok,
                      #state{socket :: gen_udp:socket(),
                             target_ip :: inet:ip_address(),
                             target_port :: 1..65535}} |
                     {ok,
                      #state{socket :: gen_udp:socket(),
                             target_ip :: inet:ip_address(),
                             target_port :: 1..65535},
                      [term()]} |
                     {stop,
                      term(),
                      #state{socket :: gen_udp:socket(),
                             target_ip :: inet:ip_address(),
                             target_port :: 1..65535}}.

handle_packet(Data, State)

-spec handle_packet(binary(),
                    #state{socket :: gen_udp:socket(),
                           target_ip :: inet:ip_address(),
                           target_port :: 1..65535}) ->
                       {ok,
                        #state{socket :: gen_udp:socket(),
                               target_ip :: inet:ip_address(),
                               target_port :: 1..65535}} |
                       {stop,
                        term(),
                        #state{socket :: gen_udp:socket(),
                               target_ip :: inet:ip_address(),
                               target_port :: 1..65535}}.

init(Req, Opts)

-spec init(masque_handler:req(), term()) ->
              {ok,
               #state{socket :: gen_udp:socket(),
                      target_ip :: inet:ip_address(),
                      target_port :: 1..65535}} |
              {stop, term()}.

terminate(Reason, State)

-spec terminate(term(),
                #state{socket :: gen_udp:socket(),
                       target_ip :: inet:ip_address(),
                       target_port :: 1..65535}) ->
                   ok.