Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

0 Neutral

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney
  1. idontknow

    Let's encrypt, desperated...

    Ah, ok. I replaced the automatic usage of dyn.org in the router by setting the update-url manually (members.dyndns.org/nic/update?system=dyndns&hostname=<domain>&myip=<ipaddr>&wildcard=NOCHG), so no ipv6-address will be set, now it's working. I'am still wondering why it worked on my side, where the router also sets both ipv4 and ipv6 addresses when making a DynDNS-Update and the ethernet-connection of my PC has been ipv6-disabled. Thank you very much for your hint, Angus!
  2. I hope someone can help: I am trying since hours to get the "OverbyteIcsX509CertsTst" example (from 01.09.2021, ICS 8.67) work on a customers pc. On my own pc it works fine, same exe. Here's what i've done in both cases : I created a new DYNDNS-Host. I set up the Dyndns-Account in the router, i checked it's working. I set up a Port-Forwarding from external port 443 to internal port 443 to the local ip address of the pc. I created some empty folders on hdd "d:\testlets\log", "d:\testlets\account", "d:\testlets\wellknown", "d:\testlets\public". Then i started the OverbyteIcsX509CertsTst.exe which i have compiled with Delphi 10.4 Version 27.0.40680.4203. I typed in the foldernames in the corresponding edits, checked "TLS-ALPN - Local Web", Private Key File Encryption AES 256, type in the complete dyndns-url, clicked on "Test Domain Challenges", which ran fine in both cases. I choose the "https://acme-v02.api.letsencrypt.org/directory" server, selected "RSA 4096..." and checked over and over again, that the settings on my pc are the same as they are on the customers one. On both sides i have comparable results, but if it comes to step "Start Challenges (5)", then the customers pc seems to get no answer after "ACME certificate order placed, automatic collection enabled". Here is a snippet from the customers logfile: 09.09.21, 17:51:47.889 [info] [20300] [main] Challenge requested for: myletsencrypttest4.dyndns.org 09.09.21, 17:51:47.891 [info] [20300] [main] ACME certificate order placed, automatic collection enabled 09.09.21, 17:52:02.612 [info] [20300] [main] 17:52:02 Challenge Done Check 09.09.21, 17:52:02.612 [info] [20300] [main] 2021-09-09T17:52:02 09.09.21, 17:52:02.612 [info] [20300] [main] Checking Acme Challenge for: myletsencrypttest4.dyndns.org 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST POST https://acme-v02.api.letsencrypt.org/acme/chall-v3/29433226520/u4mf2w {"protected":"eyJhbGciOiJSUzI1NiIsImtpZCI6Imh0dHBzOi8vYWNtZS12MDIuYXBpLmxldHNlbmNyeXB0Lm9yZy9hY21lL2FjY3QvMTk0MTk3NzYwIiwibm9uY2UiOiIwMTAxVjczNFRMN1lGaGxSNUl5eld0Qm9mM2ltYlpCYVdQSkxJaDg5VVNMZHg2NCIsInVybCI6Imh0dHBzOi8vYWNtZS12MDIuYXBpLmxldHNlbmNyeXB0Lm9yZy9hY21lL2NoYWxsLXYzLzI5NDMzMjI2NTIwL3U0bWYydyJ9","payload":"","signature":"C-Ya0PKvc4sZtGVBX2c3rQNRMMcINOIXpTmgURg7A_zqKVYDrnBJt5IOLigtZqYMbSbsfWIvvGzruA6SZo9DcPKxlmI1YolOH6zn0sn0924yolk0UoYQwOJWQ-Pc4sTrIiBS0o11KknMZb3IEOr6flQ413UgSNVUnunE9WtJzpLXAo4elEqXFWJThqjdlhsEuVRNYIOWpxJqeBzYLUXVuxdKg1HGGxKWlYhuUhU5DqINquKDX_qgKmw4Lhxqrnd3eTmnRw_1wg4SobQ777K3of2fYnVV4xoRsdp3qUaDoElkQHZa3clO0uGJDRM6A9qQADXaFTJ_cBZbSYxNqg-8hEoB8wMSXK5TcLJkaGV2nanE8TUeVCpFqzJD9R3EER29vM6nFVzrz-T-35mqjEbB1XIIjgw2XjRIvsoDFIEQd3c0x06zezEVdFDXZF_1IvCGwGOG-nuQnN-ckLw2FHD0VK8wJ30PJ-X2KKteosQzbSpCC_rOLBthAE7VO3v9DRr97sxAhaWYPbiEwO7FcXDT8T6m5Rl_oq_H-u-udlRAHlEUBtVCrEcQuqHwYAlcuesvJwiLT83PIEkGJChgab05NHit_nMSt4aTvet3YrLO7raKXuQxfn3JoDM5XlvqiKitJ1eC_dOPAeJUoon1MdRpsD16a44Djs34FDQK2Eu-Bck"} 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST Connected OK to: acme-v02.api.letsencrypt.org ( 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > POST /acme/chall-v3/29433226520/u4mf2w HTTP/1.1 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > Accept: */* 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > Accept-Encoding: gzip, deflate 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > Content-Type: application/jose+json 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > User-Agent: ICS-ACME-V8.67 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > Host: acme-v02.api.letsencrypt.org 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > Content-Length: 1015 09.09.21, 17:52:02.684 [info] [20300] [main] HTTP REST > 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < HTTP/1.1 200 OK 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Server: nginx 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Date: Thu, 09 Sep 2021 15:52:02 GMT 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Content-Type: application/json 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Content-Length: 640 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Connection: keep-alive 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Boulder-Requester: 194197760 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Cache-Control: public, max-age=0, no-cache 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Link: <https://acme-v02.api.letsencrypt.org/directory>;rel="index" 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Link: <https://acme-v02.api.letsencrypt.org/acme/authz-v3/29433226520>;rel="up" 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Location: https://acme-v02.api.letsencrypt.org/acme/chall-v3/29433226520/u4mf2w 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Replay-Nonce: 0102Edm55tArxI7QZLMQ40DeD2SvLe7DVBbbPA7wvh1WGVU 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < X-Frame-Options: DENY 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST < Strict-Transport-Security: max-age=604800 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST Request completed: 200 OK 09.09.21, 17:52:02.891 [info] [20300] [main] HTTP REST Response (length 640) { "type": "tls-alpn-01", "status": "invalid", "error": { "type": "urn:ietf:params:acme:error:connection", "detail": "Error getting validation data", "status": 400 }, "url": "https://acme-v02.api.letsencrypt.org/acme/chall-v3/29433226520/u4mf2w", "token": "Yuce1-oKueEpV8POY0bgxRFkxiQXcv3qXGGL9mA2J6A", "validationRecord": [ { "hostname": "myletsencrypttest4.dyndns.org", "port": "443", "addressesResolved": [ "", "2003:e3:efff:1972:de39:6fff:fe45:4515" ], "addressUsed": "2003:e3:efff:1972:de39:6fff:fe45:4515" } ], "validated": "2021-09-09T15:51:47Z" } 09.09.21, 17:52:02.891 [info] [20300] [main] Acme challenge Failed: Error getting validation data for: myletsencrypttest4.dyndns.org 09.09.21, 17:52:02.891 [info] [20300] [main] Cleaning up old challenge for: myletsencrypttest4.dyndns.org Does anybody know whats going wrong there? Some more informations: The customer has the same router as i have, a FritzBox 7590 with FritzOS 7.28. He has a real IPv4 address, as i have. Customer: Telekom. Windows 10 Firewall is disabled. Speedtest-Sites are showing the same external ipv4 address as the router, so it seems to be a real ipv4 address, not a carrier grade nat one...
  3. i just had an EIntOverflow in OverbyteIcsHttpProt.pas while receiving an mjpeg-stream from a camera, started some (5?) days ago. The problem was the line "Inc(FBodyLineCount)" in "procedure THttpCli.GetBodyLineNext": {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} { Data is pointed by FBodyData and FBodyDataLen as length } procedure THttpCli.GetBodyLineNext; var // P : PChar; P : Integer; // (FP 09/09/06) N, K : THttpBigInt; begin {$IFNDEF NO_DEBUG_LOG} if CheckLogOptions(loProtSpecInfo) then { V1.91 } { replaces $IFDEF DEBUG_OUTPUT } DebugLog(loProtSpecInfo, 'GetBodyLineNext begin'); {$ENDIF} if FBodyLineCount = 0 then begin FChunkLength := 0; FChunkRcvd := 0; FChunkState := httpChunkGetSize; TriggerDocBegin; {$IFDEF UseContentCoding} FContentCodingHnd.Prepare(FContentEncoding); if Assigned(FRcvdStream) then FRcvdStreamStartSize := FRcvdStream.Size else FRcvdStreamStartSize := 0; {$ENDIF} end; Inc(FBodyLineCount); // OD EIntOverflow am 07.04.2021 with FBodyLineCount: Suggest changing type to Int64. {$IFNDEF NO_DEBUG_LOG} if CheckLogOptions(loProtSpecInfo) then { V1.91 } { replaces $IFDEF DEBUG_OUTPUT } DebugLog(loProtSpecInfo, 'GetBodyLineNext FBodyDataLen=' + IntToStr(FBodyDataLen)); {$ENDIF} ... I suppose turn around to 0 with Overflow-Checks off will have some unwanted sideeffects, as initializing FChunkLength and several other variables to zero. I think, changing the vartype of the member variable "FBodyLineCount" from Integer to Int64 will solve the problem (for my lifetime).
  4. The problem was how I sent, it seems sending needs to be from within the context of the Thread where TSslWSocket is attached to to work stable. I solved the problem by deriving from TSslWSocket and adding a new Message FMsg_WM_SEND_ASYNC. If the Component receives this Message, it runs the OnSendAsync-Method from its own ThreadContext, and that's where data is send... It seems to work... TSendAnsiItem = record Data: AnsiString; end; pSendItem = ^TSendAnsiItem; TSendAnsiText = procedure(Sender: TObject; Data: AnsiString) of object; TMySslWSocket = class(TSslWSocket) protected FMsg_WM_SEND_ASYNC: UINT; FonSendAnsiAsync: TSendAnsiText; procedure AllocateMsgHandlers; override; procedure FreeMsgHandlers; override; procedure WndProc(var MsgRec: TMessage); override; public procedure SendAnsiASync(const Data: AnsiString); property OnSendAnsiAsync: TSendAnsiText read FonSendAnsiAsync write FonSendAnsiAsync; end; procedure TClientThread.NoMessagePump(Sender: TObject); begin // Nothing. Empty Message Pump. end; procedure TClientThread.SendAnsiText(Sender: TObject; Data: AnsiString); var BytesSent: Integer; begin BytesSent := TMySslWSocket(Sender).Send(TwSocketData(@Data[1]), Length(Data)); if BytesSent <> Length(Data) then Info('Fehler: Problem beim Senden!'); end; procedure TClientThread.Execute; begin ClientSocket := TMySslWSocket.Create(nil); ClientSocket.MultiThreaded := TRUE; ClientSocket.OnMessagePump := NoMessagePump; // Thread will do ClientSocket.MessageLoop later... ClientSocket.OnSendAnsiAsync := SendAnsiText; ... ClientSocket.MessageLoop; end; procedure TMySslWSocket.AllocateMsgHandlers; begin inherited AllocateMsgHandlers; FMsg_WM_SEND_ASYNC := FWndHandler.AllocateMsgHandler(Self); end; procedure TMySslWSocket.FreeMsgHandlers; begin if Assigned(FWndHandler) then begin FWndHandler.UnregisterMessage(FMsg_WM_SEND_ASYNC); end; inherited FreeMsgHandlers; end; procedure TMySslWSocket.SendAnsiASync(const Data: AnsiString); var pItem: pSendItem; begin New(pItem); pItem^.Data := Data; PostMessage(Handle, FMsg_WM_SEND_ASYNC, 0, lParam(pItem)); end; procedure TMySslWSocket.WndProc(var MsgRec: TMessage); var pItem: pSendItem; begin try with MsgRec do begin if Msg = FMsg_WM_SEND_ASYNC then begin pItem := PSendItem(MsgRec.lParam); if Assigned(FonSendAnsiAsync) then FonSendAnsiAsync(Self, pItem^.Data); System.Dispose(pItem); end else inherited WndProc(MsgRec); end; except on E: Exception do HandleBackGroundException(E, 'TMySslWSocket.WndProc'); end; end;
  5. The problem seems to be the usage of TwSocket from inside a Thread. I have left the ServerThread unchanged, but the Client is running in the VCL-Thread Context now. I have no problems anymore, the test is still running and has transferred more than 1200000 packets right now, i will test it over night. I created the TwSocket from inside Thread.Execute, told him it shall use MultiThreading, and had a message loop running inside the TClientThread. But maybe my approach to send from the vcl thread like TClientThread.Client.Send(...) was the problem, but i don't know how to send from within the ClientThread Context, if the ClientThread is running its messageloop. Thanks and Good Night, Oliver
  6. Hi Angus, thank you very much, i will look in the example code, especially the possibility to automatically order certificates sounds very good. But i really would like to understand what I'm doing wrong. Hi Fr0sT.Brutal, thank you, too. i tried a very lot of things. I suppose you mean the while loop. I know the OnDataAvailable will trigger again, if i don't read everything from the receive buffer. But even if i don't use a while loop, the client hangs after some packets... the last run was more than 18000 Packets, then the same thing... 13.08.2020 17:16:23.963 [07056] scDataAvailable 13.08.2020 17:16:23.963 [09372] MessageHandler: Server hat 18233 128KB-Pakete empfangen 13.08.2020 17:16:23.964 [09372] MessageHandler: Client hat 3 Bytes empfangen 13.08.2020 17:16:23.964 [09372] Sende 128KB, Paket #18233 13.08.2020 17:16:23.966 [07056] scDataAvailable 13.08.2020 17:16:23.966 [07056] scDataAvailable 13.08.2020 17:16:23.967 [07056] scDataAvailable 13.08.2020 17:16:23.967 [15264] TClientThread.ClientDataSent: ErrCode=0 13.08.2020 17:16:23.967 [07056] scDataAvailable 13.08.2020 17:16:23.968 [07056] scDataAvailable 13.08.2020 17:16:23.970 [07056] scDataAvailable 13.08.2020 17:16:23.971 [07056] scDataAvailable 13.08.2020 17:16:23.974 [07056] scDataAvailable 13.08.2020 17:16:23.975 [09372] MessageHandler: Server hat 18234 128KB-Pakete empfangen 13.08.2020 17:16:23.975 [09372] MessageHandler: Client hat 3 Bytes empfangen 13.08.2020 17:16:23.986 [15264] TClientThread.ClientDataSent: ErrCode=0 13.08.2020 17:16:23.986 [09372] Sende 128KB, Paket #18234 Server: procedure TServerThread.ScDataAvailable(Sender: TObject; ErrCode: Word); var Socket: TWSocketClient; pBuffer: PByte; BytesReceived: Integer; AckAnsiString: AnsiString; begin Info('scDataAvailable'); if ErrCode = 0 then begin Socket := TwSocketClient(Sender); Getmem(pBuffer, 32768); BytesReceived := Socket.Receive(pBuffer, 32768); FreeMem(pBuffer); // It's only a Test: Purge the Data, but count the Bytes if BytesReceived >= 0 then ServerBytesReceivedComplete := ServerBytesReceivedComplete + BytesReceived; if ServerBytesReceivedComplete >= 128*1024 then begin // Fine, received 128KB or more. PostMessage WM_SERVER_HAS_RECEIVED_DATA... just for logging... CountPackets := CountPackets+1; ServerBytesReceivedComplete := ServerBytesReceivedComplete - 128*1024; PostMessage(Form1.Handle, WM_SERVER_HAS_RECEIVED_DATA, CountPackets, 0); // Send AnsiString 'ACK' to Client AckAnsiString := 'ACK'; Socket.Send(TWSocketData(@AckAnsiString[1]), 3); end; end else Info('TServerThread.ScDataAvailable: ErrCode=%d', [ErrCode]); end; Client: procedure TClientThread.ClientDataAvailable(Sender: TObject; ErrCode: Word); var Socket: TWSocket; pBuffer: PByte; BytesReceived: Integer; begin // Mal so wie in D:\development\!Delphi\Components\Overbyte ICS\trunk\Samples\Delphi\SslInternet\OverbyteIcsSimpleSslCli.dproj if ErrCode = 0 then begin Socket := TwSocketClient(Sender); Getmem(pBuffer, 128); BytesReceived := Socket.Receive(pBuffer, 128); FreeMem(pBuffer); // Only a Test, purge the Bytes but count them... if BytesReceived > 0 then begin // Count them ClientBytesReceivedComplete := ClientBytesReceivedComplete + BytesReceived; if ClientBytesReceivedComplete >= Length('ACK') then begin ClientBytesReceivedComplete := ClientBytesReceivedComplete - Length('ACK'); // to keep it simple: that was 3 Bytes, in my testcase nothing else will send by the server... PostMessage(Form1.Handle, WM_CLIENT_HAS_RECEIVED_DATA, BytesReceived, 0); // Reaction in Form1: WM_CLIENT_HAS_RECEIVED_DATA -> ClientThread.Client.Send(AnsiStringWith128KB) end; end; end else Info('TClientThread.ClientDataAvailable: ErrCode=%d', [ErrCode]); end; Main (VCL-Thread): procedure TForm1.MessageHandlerClientReceivedData(var Msg: TMessage); begin Info('MessageHandler: Client has received an ACK'); if CheckBoxAutoSendAfterReceivingAck.Checked then btSendDataClick(nil); // Send 128KB-Packet to Server end; and: procedure TForm1.btSendDataClick(Sender: TObject); var i: Integer; Text: AnsiString; BytesSend: Integer; begin if Assigned(Client) then begin SetLength(Text, 128 * 1024); // 128KB for i := 1 to Length(Text) do Text[i] := AnsiChar(Ord('A')+ (i mod 26)); // ABCDEFG...XYZABCDEFG... BytesSend := Client.ClientSocket.Send(TWSocketData(@Text[1]), Length(Text)); if BytesSend = Length(Text) then begin Info('Sende 128KB, Paket #%d', [GesendetePakete]); // always comes... Inc(GesendetePakete); end else begin Info('Fehler: Paket konnte nicht gesendet werden'); // never comes... end; end else Info('Fehler: Client=nil'); end; What am I doing wrong?
  7. Hello Community, since last week I have been trying to let a TsslWSocket and a TsslWSocketServer communicate with each other. I want to get a long-term stable connection between a TCP client and a TCP server that is secured with TLS1.3. However, after a runtime of a few minutes, the data transfer breaks down. There is a client thread and a server thread. In the respective Execute method I create the socket and initialize it, call Listen (server) or Connect (client) and run the MessageLoop. After a successful SSL handshake, my client sends 128KB data packets to the server. The data arrives at the server, TwSocketClient.onDataAvailable is triggered, the bytes can be read there with TwSocketClient (Sender).Receive (pBuffer ...). When the server has received 128KB, it sends an "ACK" packet to the client (An AnsiString "ACK", 3 bytes). When the client receives the packet, it sends again 128KB of testdata. This works a few thousand, sometimes some tenthousands times, until TwSocketClient.onDataAvailable is suddenly no longer called. There is no OnSessionClosed, no onError, no onException and also no onBgException that would indicate a problem. Apparently the problem is on the client side: A running Wireshark shows an [ACK] packet from the server to the client as last entry. Further clicks on the "Manual Send" button do not lead to any further lines in the Wireshark log. When this state has been reached another client can connect to the server without any problems, so the server is not completely dead. I have no idea what I could do wrong ... Maybe it's not ok to send in the context of another thread? But how is that supposed to work when the client thread is blocked by the MessageLoop? Simultaneous web browsing leads to the problem faster. When I look at any website, it usually takes less than half a minute to see the problem. My test project is attached. I would be interested to know if you have observed the same problem and if anyone has a guess as to what might be the cause ... The project is complete, the Win32 folder also contains the certificate used for testing ... Usage: Enter your own IP address, press the "btCreateStart" button, then the "btSendData Manual Send" button. The "logICStest.log" file in the program directory grows until the problem occurs ... Thanks in advance... P.S: I have already tried not to send after receiving the ACK packet, but cyclically via timer or thread. If you can select both in the test project with checkboxes, the result is the same. The problem does not only occur with TLS1.3, also with TLS1.2. I even think it shows up without encryption, just takes longer ... I crossposted this in the german Delphi-Praxis in german language (https://www.delphipraxis.net/205223-stabile-tcp-verbindung-mit-ics-ich-kriegs-nicht-hin.html)... Test Overbyte ISC Client und Server.7z