I am playing a game named "Planetside 2" and since a few days many users including me have high ping issues on a specific server, while others have not.
Therefore I wanted to try to traceroute / ping the Server IP, to find out which server node causes the high ping issues.
However it seems like the Server has some kind of Firewall that protects itself from being pinged by ICMP. Whenever I use "ping 69.174.216.23" (the ip is public on google so I can share it here) I get a timeout response.
So I used Wireshark to find out how the Game Client communicates with the Server and I found out that it's using UDP to ping the Server IP:Port.
However the Server has only a few Ports open for example for the Server IP: 69.174.216.23 The following ports are the only ones that it communicates with: { 20112, 20113, 20143, 20156, 20157, 20164, 20168, 20175 }
If I simulate that, sending a 1Byte UDP Packet to the Server it does not work, but if I add one of the Ports behind it 69.174.216.23:20112 and send a 1Byte UDP Packet I get a response.
I made a simple python script like that which works fine for that purpose:
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)
So since I am not able to traceroute or ping the Server IP using ICMP, I wonder if there is another possible way, like using an approach like I did with udp ip:port instead?
I searched around a bit and found out that you can udp traceroute but that uses its probe on UDP port number 33434 and since the Targets Server IP only listens / responds to a few ports (20112, 20113, 20143, 20156, 20157, 20164, 20168, 20175).
So I tried it this way:
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;
}
}
}
However here the issue is that as soon as i set udpClient.Client.Ttl = ttl; it doesn't get any anymore here UdpReceiveResult result = await udpClient.ReceiveAsync(); but if I comment the TTL out it works fine.
So now I am stuck and wonder if there is another possible way to traceroute the IP?
Doesn't matter which enviroment, linux, c#, python, powershell im fine with that, just to get an idea.