
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.)