Servidor y cliente STUN para Delphi

· Componentes

STUN (Session Traversal Utilities for NAT) es un protocolo IETF usado para audio y vídeo en tiempo real sobre redes IP. STUN es un protocolo cliente-servidor; un servidor STUN normalmente opera tanto sobre UDP como sobre TCP y escucha en el puerto 3478.

El objetivo principal del protocolo STUN es permitir que un dispositivo que se ejecuta detrás de un NAT descubra su IP pública y qué tipo de NAT tiene.

STUN proporciona un mecanismo para comunicar peers que están detrás de un NAT. Los peers envían una petición a un servidor STUN para conocer cuál es su dirección IP pública y su puerto. Las binding requests enviadas del cliente al servidor sirven para determinar las asignaciones de IP y puertos que realizan los NAT. El cliente STUN envía una Binding request al servidor STUN, el servidor examina la IP y puerto de origen usados por el cliente y devuelve esta información al cliente.

Servidor STUN

TsgcSTUNServer es el servidor que implementa el protocolo STUN y permite procesar binding requests procedentes de clientes STUN.

El servidor STUN se puede configurar con o sin autenticación, puede verificar el Fingerprint Attribute, enviar un servidor alternativo y más.

Uso básico

Normalmente los servidores STUN se ejecutan en el puerto UDP 3478 y no requieren autenticación, así que para configurar un servidor STUN basta con establecer el puerto de escucha (por defecto 3478) y arrancar el servidor.

Configura el servidor

Pon la propiedad Active = True para arrancar el servidor STUN.

Mira el siguiente código Delphi que muestra cómo arrancar un nuevo servidor STUN en Delphi.

oSTUN := TsgcSTUNServer.Create(nil);
oSTUN.Port := 3478;
oSTUN.Active := True; 

Long-Term Credentials 

Habitualmente los servidores STUN se configuran sin autenticación, de modo que cualquier cliente STUN puede enviar una binding request y esperar una respuesta del servidor sin autenticación.

El servidor STUN de sgcWebSockets admite Long-Term Credentials, por lo que puedes configurar TsgcSTUNServer para que sólo permita binding requests con información de Long-Term credentials.

Para configurarlo, accede a la propiedad STUNOptions.Authorization y habilítala.

A continuación accede a la propiedad LongTermCredentials y habilítala. Por defecto, este tipo de autorización ya viene configurada con una cadena Realm y con un valor por defecto de StaleNonce de 10 minutos (= 600 segundos).

Mira el siguiente código Delphi que muestra cómo crear un nuevo servidor STUN en Delphi con Long-Term Credentials habilitadas.

oSTUN := TsgcSTUNServer.Create(nil);
oSTUN.Port := 3478;
oSTUN.STUNOptions.Authentication.Enabled := True;
oSTUN.STUNOptions.Authentication.LongTermCredentials.Enabled := True;
oSTUN.STUNOptions.Authentication.LongTermCredentials.Realm := 'sgcWebSockets';
oSTUN.STUNOptions.Authentication.LongTermCredentials.StaleNonce := 600;
oSTUN.Active := True;
procedure OnSTUNRequestAuthorization(Sender: TObject; const aRequest: TsgcSTUN_Message; const aUsername, aRealm: string; var Password: string);
begin
  if aUsername = 'my-user' then
    Password := 'my-password';
end; 

Cliente STUN 

 TsgcSTUNClient es el cliente que implementa el protocolo STUN y permite enviar binding requests a servidores STUN.

El componente permite usar UDP y TCP como transporte, e cuando se usa UDP como transporte implementa un mecanismo de retransmisión para reenviar peticiones si la respuesta no llega tras un breve intervalo de tiempo.

Uso básico

Normalmente los servidores STUN se ejecutan en el puerto UDP 3478 y no requieren autenticación, así que para enviar una STUN binding request rellena las propiedades del servidor para que el cliente sepa dónde conectarse y maneja los eventos en los que el componente recibirá la respuesta del servidor.

Configura el servidor

Llama al método SendRequest para enviar una binding request al servidor STUN.

Maneja los eventos

Mira el siguiente código Delphi que muestra cómo crear un nuevo cliente STUN en Delphi y conectarse a un servidor STUN.




oSTUN := TsgcSTUNClient.Create(nil);
oSTUN.Host := 'stun.sgcwebsockets.com';
oSTUN.Port := 3478;
oSTUN.SendRequest;
procedure OnSTUNResponseSuccess(Sender: TObject; const aMessage: TsgcSTUN_Message; const aBinding: TsgcSTUN_ResponseBinding);
begin
  DoLog('Remote IP: ' + aBinding.RemoteIP + '. Remote Port: ' + IntToStr(aBinding.RemotePort));
end;
procedure OnSTUNResponseError(Sender: TObject; const aMessage: TsgcSTUN_Message; const aError: TsgcSTUN_ResponseError);
begin
  DoLog('Error: ' + IntToStr(aError.Code) + ' ' + aError.Reason);
end; 
});