¿Traceroute usando UDP en lugar de ICMP?

¿Traceroute usando UDP en lugar de ICMP?

Estoy jugando un juego llamado "Planetside 2" y desde hace unos días muchos usuarios, incluido yo, tienen problemas de ping elevados en un servidor específico, mientras que otros no.

Por lo tanto, quería intentar rastrear/hacer ping a la IP del servidor para descubrir qué nodo del servidor causa los problemas de ping alto.

Sin embargo, parece que el servidor tiene algún tipo de firewall que lo protege de que ICMP le haga ping. Cada vez que uso "ping 69.174.216.23" (la IP es pública en Google, así que puedo compartirla aquí) obtengo una respuesta de tiempo de espera.

Entonces utilicé Wireshark para descubrir cómo se comunica el cliente del juego con el servidor y descubrí que está usando UDP para hacer ping a la IP del servidor: puerto.

Sin embargo, el servidor tiene solo unos pocos puertos abiertos, por ejemplo para la IP del servidor: 69.174.216.23 Los siguientes puertos son los únicos con los que se comunica: { 20112, 20113, 20143, 20156, 20157, 20164, 20168, 20175 }

Si simulo eso, enviar un paquete UDP de 1 Byte al servidor no funciona, pero si agrego uno de los puertos detrás de él 69.174.216.23:20112 y envío un paquete UDP de 1 Byte obtengo una respuesta.

Hice un script en Python simple como ese que funciona bien para ese propósito:

import socket
import time

def udp_ping(destination_ip, destination_port):
    try:
        # Create a UDP socket
        udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        # Set a timeout for receiving responses (in seconds)
        udp_socket.settimeout(5)
        
        # Record the time just before sending the message
        start_time = time.time()
        
        # Send a message to the destination
        udp_socket.sendto(b'PONG', (destination_ip, destination_port))
        
        # Receive a response
        response, address = udp_socket.recvfrom(1024)
        
        # Record the time when the response is received
        end_time = time.time()
        
        # Calculate round-trip time (RTT) in milliseconds
        rtt_ms = (end_time - start_time) * 1000
        
        print("Received response from {}: {} (RTT: {:.2f} ms)".format(address, response.decode(), rtt_ms))
    
    except socket.timeout:
        print("No response received.")

    finally:
        udp_socket.close()

destination_ip = '69.174.216.23'
destination_port = 20112 
udp_ping(destination_ip, destination_port)

Entonces, dado que no puedo rastrear la ruta o hacer ping a la IP del servidor usando ICMP, me pregunto si hay otra forma posible, como usar un enfoque como lo hice con udp ip:port.

Busqué un poco y descubrí que puedes udp traceroute pero eso usa su sonda en el puerto UDP número 33434 y dado que la IP del servidor de destino solo escucha/responde a unos pocos puertos (20112, 20113, 20143, 20156, 20157, 20164, 20168, 20175).

Así que lo intenté de esta manera:

using (UdpClient udpClient = new UdpClient())
{
    udpClient.Client.ReceiveTimeout = 3000;

    for (short ttl = 1; ttl <= maxHops; ttl++)
    {
        string message = $"Traceroute[{ttl}]: ";

        // Set the TTL option for the UDP socket
        udpClient.Client.Ttl = ttl;

        // Send a UDP packet to the target
        udpClient.Send(new byte[1], 1, targetIp, targetPort);

        message += $"UDP packet sent to {targetIp}:{targetPort}";

        try
        {
            // Receive response from the target or an intermediate router
            UdpReceiveResult result = await udpClient.ReceiveAsync();

            IPAddress senderIp = result.RemoteEndPoint.Address;

            if (senderIp.Equals(targetIp))
            {
                targetReached = true;
                message += " - Target reached";
            }
            else
            {
                message += $" - Received response from {senderIp}";
            }
        }
        catch (SocketException ex)
        {
            if (ex.SocketErrorCode == SocketError.TimedOut)
            {
                message += " - Timeout";
            }
            else
            {
                message += $" - Error: {ex.Message}";
            }
        }
        catch (Exception ex)
        {
            message += $" - Error: {ex.Message}";
        }

        if (targetReached)
        {
            break;
        }
    }
}

Sin embargo, aquí el problema es que tan pronto como udpClient.Client.Ttl = ttl;lo configuro ya no aparece aquí, UdpReceiveResult result = await udpClient.ReceiveAsync();pero si comento el TTL, funciona bien.

Así que ahora estoy atascado y me pregunto si existe otra forma posible de rastrear la IP.

No importa qué entorno, Linux, C#, Python, PowerShell, estoy de acuerdo con eso, solo para tener una idea.

Respuesta1

Las sondas Traceroute no requieren que el servidor tenga nada abierto, ya que su propósito es generar respuestas delintermedioenrutadores, no del host final; En realidad, nunca llegan al anfitrión final. El tipo real de sonda no importa; todos ellos dan como resultado el mismo tipo de respuesta.

Pero incluso si la sonda fuera UDP, la respuesta de las sondas de traceroute no es un paquete UDP y no se entregará a través de Recibir(); en su lugar, siempre obtendrá un ICMP.TTL Exceeded errorpaquete, que podría reportarse como una excepción o podría requerir alguna opción de socket especial.

(La única excepción a lo anterior es la sonda "final" que tiene un TTL lo suficientemente grande como para llegar al host. Si el host no responde, entonces el seguimiento se bloqueará en ese punto, pero debería tener tiempos de espera para eso. situación porque los enrutadores intermediostambiénse les permite no responder.)

información relacionada