Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 17:19
    PizzaProgram commented #412
  • May 18 15:34
    rlebeau labeled #192
  • May 18 15:34
    rlebeau labeled #192
  • May 17 18:54
    BretBordwell commented #192
  • May 17 11:00
    PizzaProgram commented #412
  • May 17 10:58
    PizzaProgram synchronize #412
  • May 17 10:52
    PizzaProgram synchronize #412
  • May 17 10:50
    PizzaProgram synchronize #412
  • May 17 10:17
    PizzaProgram synchronize #412
  • May 16 18:32
    rlebeau commented #412
  • May 15 16:24
    PizzaProgram opened #412
  • May 11 17:53

    rlebeau on master

    upgraded Delphi XE projects by … added Delphi XE project group Merge pull request #411 from co… (compare)

  • May 11 17:53
    rlebeau closed #411
  • May 11 17:53
    rlebeau labeled #411
  • May 11 17:53
    rlebeau labeled #411
  • May 10 19:33
    corneliusdavid opened #411
  • May 06 21:08
    rlebeau labeled #410
  • May 06 21:08
    rlebeau labeled #410
  • May 06 21:08
    rlebeau opened #410
  • Apr 27 06:41
    lloydbates closed #408
Chad Adams
@chadeadams_gitlab
TIdThreadSafeStringList - what unit is that in?
Idthreadsage
safe
I found it
thanks!
Chad Adams
@chadeadams_gitlab
@rlebeau - what datatype is list? threadsafetstring?
Remy Lebeau
@rlebeau
@chadeadams_gitlab TStringList, which you can see by just looking at the declaration of Lock()
Chad Adams
@chadeadams_gitlab
     ok, it works except for the list.clear. if i have that the application exits                                                                                                      
Remy Lebeau
@rlebeau

@chadeadams_gitlab Your code is crashing because you are not checking if the list is empty before accessing its contents. To avoid that, you should be using a for or while loop instead of a repeat loop.

Also, there are other problems with your code.

You are creating the reading thread twice, once BEFORE you connect the client to the server, and again AFTER connecting. Get rid of the 1st create.

And, you are still calling CheckForDataOnSource(), ReadChar(), and ReadLn() in your main code, which is going to interfer with the ReadLn() in the reading thread. You can't read from the same socket in multiple threads at the same time like you are doing (without synchronizing them), otherwise you are going to corrupt the contents of the InputBuffer and mess up your communications. The whole point of using a dedicated reading thread is that it performs ALL of the reading from the socket, and then delegates the processing of the received data as needed.

Chad Adams
@chadeadams_gitlab
ok, thank you. let me look through it.
the char input routine is on the telnet connection, however. Not the thread we created with the tcp client.
anything from cyberio is dealing with the telnet connection/client. not the tcp client.
Remy Lebeau
@rlebeau
@chadeadams_gitlab ok then. But the other issues still stand
Chad Adams
@chadeadams_gitlab
try
    while (list.count <> iCnt) do
    begin
      Write(list.Strings[iCnt]);
      LoadMsgs(list.Strings[iCnt]);
      PrintContent;
      iCnt := iCnt + 1;
    end;
     list.clear;
    //list.Clear;
  finally
    Msgs.unlock;
//    Msgs.Clear;

  end;
finally got code formatting to work lol!
i fixed it by changing it to this:
well the list issue
Chad Adams
@chadeadams_gitlab
So for auto printing the information the client sends
since you cannot use a separate thread for updating the screen, how would you suggest i look into running a loop with this function we just created? so that it will load all the messages that come in? With this, I still have to run this code to LoadMsg and PrintContent to the screen. I need a way to run those automatically, without causing the interface to run out of memory or stop responding.
Remy Lebeau
@rlebeau

@chadeadams_gitlab for the list issue, I would use either:

try
  while (iCnt < list.Count) do
  begin
    Write(list.Strings[iCnt]);
    LoadMsgs(list.Strings[iCnt]);
    PrintContent;
    Inc(iCnt);
  end;
  list.Clear;
finally
  Msgs.Unlock;
end;

Or:

try
  for iCnt := 0 to list.Count-1 do
  begin
    Write(list.Strings[iCnt]);
    LoadMsgs(list.Strings[iCnt]);
    PrintContent;
  end;
  list.Clear;
finally
  Msgs.Unlock;
end;

Or:

try
  while (list.Count > 0) do
  begin
    Write(list.Strings[0]);
    LoadMsgs(list.Strings[0]);
    PrintContent;
    list.Remove(0);
  end;
finally
  Msgs.Unlock;
end;
@chadeadams_gitlab for the auto-update issue, you are already checking the list for pending messages in the main UI thread in between other operations, so I don't see what the actual issue is. But, given what you are trying to do, I would probably redesign this code from scratch to have everything work asynchronously, TCP input and Telnet input in their own separate threads that process locally as needed and actively notify the UI thread whenever there is something needing to be displayed, rather than doing a bulk of the work in the main UI thread and using a queue of strings to check for pending work. But that is just me.
Chad Adams
@chadeadams_gitlab
The list issue is: if you sit thtere and dont type anything, you would never update the content..
The LoadMsgs func would never run, therefore, all the above code would never execute.
Remy Lebeau
@rlebeau
@chadeadams_gitlab Well, that is your own fault, for tying the processing of TCP client messages inside the processing of Telnet messages. Do them separately and independantly of each other.
arend-c
@arend-c

I was in here a while ago with an issue that only happened on iOS when using mobile data on a network that uses IPv6 protocols. The issue was with the getaddrinfo() function call in IdStackVCLPosix.pas Ln 987 which returned the error:

Error resolving Address [URL]: nodename nor servname provided, or not known (8)

I fixed this on the TIdHTTP component by adding square brackets around the URL to force an IPv6 lookup in the getaddrinfo() function.

I am now tying to use the TIdSNTP component and am having the same issue. When the component's IPVersion variable is set to IPv4 I get the above 8 error. When set to IPv6 I get a "Socket Error # 11001 - Host not found.".

The Host variable doesn't like square brackets either. I'm using "pool.ntp.org" but "[pool.ntp.org]" doesn't work.

Would there be anything else I can try or am I out of luck?

Remy Lebeau
@rlebeau
@arend-c the square bracket trick only works for URLs. It is not needed for other protocols. Please provide an example that is not working for you. AFAIK, setting IPVersion to IPv6 should be working fine. Also, which version of Indy are you using? In the latest, the call to getaddrinfo is on line 996, not 987.
arend-c
@arend-c
I'm using C++ Builder 11 so whichever version comes with that, not sure if it can be upgraded can it? I will install 11.1 and see if Indy gets updated with that.
arend-c
@arend-c
wasn't able to debug on an iOS device before but finally was able to and found that setting the component to IPv6 does remove the error from the getaddrinfo() function, the error is now a socket error in the TIdStackVCLPosix.Connect function in IdStackVCLPosix.pas which for my version is line 771 (triggers in the CheckForSocketError(Posix.SysSocket.connect(ASocket, LAddr, SizeOf(LAddrIPv6))); function on line 790). Not sure what other information to give or if you can help at all
Remy Lebeau
@rlebeau
@arend-c can you please show the actual code in your project that is failing? Provided the Host and Port are set correctly, and the server's IP is reachable, and it supports IPv6, then the connect() should work. What is the actual error it is throwing now?
arend-c
@arend-c
ok, i'm an idiot and wasn't setting the host properly, I was too fixated on the mobile data issue, sorry for wasting your time
Remy Lebeau
@rlebeau
@arend-c no worries
Bob Plant
@BobPlant87_twitter
@rlebeau just noticed that TidIMAP4.pas lacks the ID method (see "3.1. ID Command" at https://www.ietf.org/rfc/rfc2971.txt)
It can be critical when requesting mails from some services (e.g. chineese like 163.com)
This is how it should look:
function TIdIMAP4.ID(const AName, AVersion, AVendor, ASupportEmail: UnicodeString): Boolean;
const
  LCFormat = ' "%s" "%s"';
  LCFinal = ' (%s)';
var
  LData: UnicodeString;
begin
  Result := False;
  CheckConnectionState(csAuthenticated);

  LData := string.Empty;

  if not AName.IsEmpty then
    LData := LData + Format(LCFormat, ['name', AName]);
  if not AVersion.IsEmpty then
    LData := LData + Format(LCFormat, ['version', AVersion]);
  if not AVendor.IsEmpty then
    LData := LData + Format(LCFormat, ['vendor', AVendor]);
  if not ASupportEmail.IsEmpty then
    LData := LData + Format(LCFormat, ['support-email', ASupportEmail]);

  LData := Format(LCFinal, [Trim(LData)]);

  SendCmd(NewCmdCounter, IMAP4Commands[cmdID] + LData, ['OK']); // IMAP4Commands[cmdID]  = 'ID'
  if LastCmdResult.Code = IMAP_OK then
    Result := True;
end;
Remy Lebeau
@rlebeau
@BobPlant87_twitter there are other IMAP extensions that are not implemented yet (IDLE, etc). But I will consider this one, it looks simple enough. I have opened a ticket for it: IndySockets/Indy#405. But, reading the RFC, I see there are other fields and formats available than just what you have shown. So I'll want this to be more flexible, like taking a user-defined array of name/value pairs, similar to how (UID)SearchMailBox() works.
Chad Adams
@chadeadams_gitlab
@rlebeau My telnet server works fine. however, occasionally, if during a routine where its printing output (CP437, ANSI) that may take a short time, if a user presses keys during that time, it will disconnect. Is this something with buffering possibly? I set the buffers to 1024 for read and write OnConnect but that doesnt seem to help. I also put some pause (sleeps) in but is there anything in the telnet server itself (buffers,etc) that could cause it to disconnect if the server receives commands while writestring from AContext?
Remy Lebeau
@rlebeau
@chadeadams_gitlab reading and writing are handled separately and independantly by the OS, so the client sending data to your server while your server is sending data to the client is perfectly fine. Is the initial disconnect happening on the client side or the server side? Is there a FIN packet being sent, or a RSET packet? If so, who is sending it first? If it is the server, is there perhaps an uncaught exception being raised that is stopping the thread that is assigned to the client?
Chad Adams
@chadeadams_gitlab
The sever stays up, i cant tell anymore yhan that. I know the client wouldn’t be sending those packets.. its pretty complex at this point and hard to pinpoint
the server is simy running a print loop and if you type too much it disconnects
maybe its an exception or invalid command but i coded for invalid commands. It does this in most menus, as well
Remy Lebeau
@rlebeau
@chadeadams_gitlab then I suggesst you use a packet sniffer like Wireshark to capture the raw network traffic and see exactly who is disconnecting from who first. "Typing too much" would not normally cause a disconnect, unless maybe the client is exceeding the server's AContext.Connection.IOHandler.MaxLineLength setting, causing an exception in IOHandler.ReadLn() (are you even calling that?). Hard to say without seeing your actual code
Chad Adams
@chadeadams_gitlab
Does indy have a gopher server
Remy Lebeau
@rlebeau
@chadeadams_gitlab Indy has TIdGopher and TIdGopherServer components. I've never used them, though
Pea-ACS
@Pea-ACS

Is there a detailed explaination/documentation in context of Indy about what the difference is between the three certfificates used in SSLOptions; SSLOptions.Certfile, SSLOptions.KeyFile and SSLOptions.RootCertFile? For instance; Would/Could one use a self-signed CA certificate in SSLOptions.RootCertFile?

Also, do any of the certificates get transferred between the peers during communication?

In a IdTCPServer and IdTCPClient environment, would it be good to have the same RootCertFile on both sides (Server and Client)? Would it matter? I would like both sides to verify its peer. Can PassThrough be set any place apart from OnConnect on the Server side and should it be set on the Client side and where?

Remy Lebeau
@rlebeau

@Pea-ACS no, there is no such documentation in Indy. All I can tell you is that:

  • CertFile is used with OpenSSL's SSL_CTX_use_certificate_file/SSL_CTX_use_certificate_chain_file functions
  • KeyFile is used with OpenSSL's SSL_CTX_use_PrivateKey_file function
  • RootCertFile is used with OpenSSL's SSL_load_client_CA_file+SSL_CTX_set_client_CA_list and SSL_CTX_load_verify_locations functions.

So, you will have to read OpenSSL's documentation for how those functions work.

It is possible to use a self-signed certificate, as long as the peer validates or ignores it. And obviously, peers do have to exchange certificates during communications in order to validate them.

Yes, PassThrough can be set pretty much any time, but must be set to False on both sides so they both performs the handshake. If PassThrough is set to False before a socket is connected, the TLS handshake is initiated immediately upon the socket being connected before any other data is exchanged (ie, implicit TLS style protocols, like HTTPS), or it can be set to False after the connection is established and data has been exchanged first (ie, explicit STARTTLS style protocols, like SMTP/IMAP/POP3).

Pea-ACS
@Pea-ACS
  • CertFile is used with OpenSSL's SSL_CTX_use_certificate_file/SSL_CTX_use_certificate_chain_file functions
  • KeyFile is used with OpenSSL's SSL_CTX_use_PrivateKey_file function
  • RootCertFile is used with OpenSSL's SSL_load_client_CA_file+SSL_CTX_set_client_CA_list and SSL_CTX_load_verify_locations functions.

So, you will have to read OpenSSL's documentation for how those functions work.

That is perfect. Those functions will have lots of information. Thanks

And obviously, peers do have to exchange certificates during communications in order to validate them.

Which certificates get transferred? CertFile, KeyFile or RootCertFile?

Remy Lebeau
@rlebeau
@Pea-ACS obviously not the KeyFile since that is a private key. As for the other two, I can't really answer that for sure, but I would imagine that it is the CertFile that is shared, and the RootCertFile is used to validate the peer's certificate.
Pea-ACS
@Pea-ACS
@rlebeau
Thank you Remy. Much appreciated
Pea-ACS
@Pea-ACS

@rlebeau By using Wireshark I saw that on a VerifyMode := [] the server would transfer its CertFile and its RootCertFile.

I suspect that is why it is important to use an intermediate RootCertFile and have the root CA available to verify the chain against. It will make verification alot more secure. Am I correct?

Remy Lebeau
@rlebeau
@Pea-ACS probably