Recent

Author Topic: [Solved] Implausible PING RTT with Synapse when using IPV6  (Read 755 times)

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
[Solved] Implausible PING RTT with Synapse when using IPV6
« on: March 25, 2023, 09:34:19 pm »
Hi all,

I use quite straightforward code to do a PING test, platform is Windows 10x64,  Lazarus 2.2.0, Laz_Synapse 40.1:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DoPingSuccess(const aPingSender: TPingSend);
  2. begin
  3.   PingResultEdit.Text := Format('Success, RTT=%dms', [aPingSender.PingTime]);
  4.   RTTListChartSource.Add(now, aPingSender.PingTime);
  5. end;
  6.  
  7. procedure TForm1.DoPingFailed(const aPingSender: TPingSend);
  8. begin
  9.   PingResultEdit.Text := Format('Failed, reason=%d (%s)', [aPingSender.ReplyError, aPingSender.ReplyErrorDesc]);
  10.   RTTListChartSource.Add(now, 0, 'F');
  11. end;
  12.  
  13. procedure TForm1.doPing(anIP: string);
  14.  
  15. var
  16.   PingSend: TPINGSend;
  17.  
  18. begin
  19.   PingSend := TPingSend.Create;
  20.   if PingSend.Ping(anIp) then
  21.     doPingSuccess(Pingsend)
  22.   else
  23.     doPingFailed(PingSend);
  24.   FreeAndNil(PingSend);
  25. end;

When I give it an IPV4 address, everything is fine. If I give it the IPV6 address (of the same host) or any other host I get RTT times of around 3000000ms, while "real" PING times are around 40ms.

Before I wave the "Bug" flag of the Synapse project ... does anyone find an error in my code?

Thnx, Armin.



« Last Edit: March 26, 2023, 08:36:16 pm by Nimral »
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

Thaddy

  • Hero Member
  • *****
  • Posts: 14172
  • Probably until I exterminate Putin.
Re: impossible PING RTT with Synapse when using IPV6
« Reply #1 on: March 25, 2023, 09:42:05 pm »
1) ping requests should be dropped by the server anyway.
2) Synapse has no real IPv6 support.

What is your intention? then I can give a proper answer.
( ping being a well known - and very serious! - security risk: https://en.wikipedia.org/wiki/Ping_flood )

Why you want to use it?
« Last Edit: March 25, 2023, 09:47:36 pm by Thaddy »
Specialize a type, not a var.

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: impossible PING RTT with Synapse when using IPV6
« Reply #2 on: March 25, 2023, 11:44:48 pm »
Thaddy,

I can for sure confirm that the target server does not have any ICMP bandwith throttling issue, since this code does give me the expected values for the RTT:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.doPing(anIP: string);
  2.  
  3. var
  4.   PingSend: TPINGSend;
  5.   dt:TDateTime;
  6.   ms:word;
  7.  
  8. begin
  9.   PingSend := TPingSend.Create;
  10.   dt := now();
  11.   if PingSend.Ping(anIp) then
  12.     begin
  13.     ms := MilliSecondsBetween(dt,now());
  14.     // doPingSuccess(Pingsend);
  15.     PingResultEdit.Text := Format('Success, RTT=%dms (%dms)', [PingSend.PingTime,ms]);
  16.     end
  17.   else
  18.     doPingFailed(PingSend);
  19.   FreeAndNil(PingSend);
  20. end;  

The results of this approach are almost the same as when testing with IPv4, and in the range between 40ms and say 200ms, which looks OK for me: "Success, RTT=2883584ms (47ms)"

The objective of the code is quite simple: I need to test the connection to a remote server from time to time to make an instable VPN connection reconnect when it drops out. If I don't get an answer, I need to restart the VPN client. I ping the server once every minute, which should not cause any traffic issues. Accuracy to the millisecond is not required, and my workaround works sufficiently.

Nevertheless I suspect there could be a bug in Synapse decoding the return values from the buffer returned by Windows, when IPV6 is in use.

Armin.
« Last Edit: March 26, 2023, 11:25:14 am by Nimral »
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: impossible PING RTT with Synapse when using IPV6
« Reply #3 on: March 26, 2023, 12:21:12 pm »
Think I found it myself.

There seems to be a bug in Synapse when mapping the ICMP response. The bytes are shifted by two, only IPV6 is affected.

This code works:

Code: Pascal  [Select][+][-]
  1.     PingResultEdit.Text := Format('Success, RTT=%dms (%dms)', [PingSend.PingTime SHR 16,ms]);
  2.  
  3.  

The result is: "Success, RTT=40ms (31ms)", which makes perfect sense to me.

I'll try to bring this issue to the attention of the Synapse team.

(curiousity took over ... after some research, this is my theory)

The bug lies in pingsend function TPINGSend.InternalPingIpHlp, line 614. (Here: Line 8.)

Code: Pascal  [Select][+][-]
  1.       if pingIp6 then
  2.       begin
  3.         FillChar(ip6, sizeof(ip6), 0);
  4.         r := Icmp6SendEcho2(PingHandle, nil, nil, nil, @ip6, @Fsin,
  5.           PAnsichar(FBuffer), length(FBuffer), @ipo, pAnsichar(RBuff), length(RBuff), FTimeout);
  6.         if r > 0 then
  7.         begin
  8.           // --> RBuff := #0 + #0 + RBuff; <--
  9.           ip6reply := PICMPV6_ECHO_REPLY(pointer(RBuff));
  10.           FPingTime := ip6reply^.RoundTripTime;
  11.           ip6reply^.Address.sin6_family := AF_INET6;
  12.           FReplyFrom := GetSinIp(TVarSin(ip6reply^.Address));
  13.           TranslateErrorIpHlp(ip6reply^.Status);
  14.           Result := True;
  15.         end;
  16.       end
  17.  

RBuff := #0 + #0 + RBuff; shifts the whole buffer by two bytes. I don't see any reason for this, maybe the author meant to code RBuff := RBuff + #0 + #0; to terminate the string. if I comment out his line, ping works flawlessly with IPV6. Since I don't like to compile my projects with modified libraries, I finally filed a bug in the Synapse Bugtracker (https://sourceforge.net/p/synalist/bugs/71/), and made this workaround:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DoPingSuccess(const aPingSender: TPingSend);
  2.  
  3. var pt: LongInt;
  4.  
  5. begin
  6.   pt := aPingSender.PingTime;
  7.   // Synapse V40 bug? IPV6 PingTime seems to be shifted left by 2 bytes.
  8.   // A RTT of more than 65.5 seconds seems impossible
  9.   // trying to workaround the bug by reversing the shift
  10.   if pt > $FFFF then
  11.     pt := pt SHR 16;
  12.   PingResultEdit.Text := Format('Success, RTT=%dms', [pt]);
  13.   RTTListChartSource.Add(now,pt);
  14. end;
  15.  

This gives me the results shown in the attachment.

Armin.

« Last Edit: March 26, 2023, 04:57:22 pm by Nimral »
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: impossible PING RTT with Synapse when using IPV6
« Reply #4 on: March 26, 2023, 07:46:03 pm »
Confirmed and fixed by the Snapse folks (Geby) within roughly an hour :-)

I love Lazarus :-)

Armin
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

krolikbest

  • Full Member
  • ***
  • Posts: 246
Re: [Solved] Implausible PING RTT with Synapse when using IPV6
« Reply #5 on: March 27, 2023, 10:47:33 pm »
Thanks for info.

 

TinyPortal © 2005-2018