cURL / Mailing Lists / curl-library / Single Mail

curl-library

POP3 not using same connection for multiple requests when using starttls

From: Steve Holme <steve_holme_at_hotmail.com>
Date: Wed, 2 Nov 2011 19:06:05 +0000

Dear all,

I am currently having an issue when trying to retrieve multiple POP3
messages over the same connection when the connection starts off as a normal
pop3 connection and then changes to an SSL connection via starttls.

A simplified version of my code is as follows:

        // Initialise the curl interface
        CURL* curl = curl_easy_init();

        // Set our login details
        curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
        curl_easy_setopt(curl, CURLOPT_PASSWORD, "pw");

        // Set our SSL options
        curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY);"
        curl_easy_setopt(curl, CURLOPT_CAPATH, "cacert.pem");

        // Perform the list messages action
        curl_easy_perform("pop3://mail.domain.com");

        // Retrieve the first message
        curl_easy_perform("pop3://mail.domain.com/1");

        // Retrieve the second message
        curl_easy_perform("pop3://mail.domain.com/2");

The first curl_easy_perform() will connect using connection #0, the second
on #1 and the third on #2. My understanding is that the second and third
operations should reuse connection #0.

If I modify the code and remove the two SSL options then everything works as
expected ;-)

Similarly I can reproduce this using the curl command line interface
(v7.22.0 - Windows x64 with SSL):

        curl -v pop3://mail.domain.com pop3://mail.domain.com/1
pop3://mail.domain.coms.com/2 --user user:pw --ssl --cacert cacert.pem

Whereas the following works successfully:

        curl -v pop3://mail.domain.com pop3://mail.domain.com/1
pop3://mail.domain.coms.com/2 --user user:pw

I have attempted to debug libcurl and the problem appears to be in url.c in
the ConnectionExists() function when it is trying to determine if an
existing connection should be reused. A fair way through the function it
checks an existing connection's handler flags against the new connection's
handler flags to see if the SSL flag is the same:

    if((needle->handler->flags&PROTOPT_SSL) !=
       (check->handler->flags&PROTOPT_SSL))
      /* don't do mixed SSL and non-SSL connections */
      continue;

In this section of code the the if statement will cause the "continue"
statement to fire because the existing connection "check" has the flags
value of 5, which includes bit 0 (PROTOPT_SSL) being set whilst the new
connection "needle" has the value 4 which has bit 0 clear.

Because I am not too familiar with this area of code I was wondering if
there is any way of performing an additional check on new connection to see
if it is about to enter SSL mode and if so don't move on to the next item in
the loop but instead continue checking the rest of the criteria needed to
return the correct reuse value?

Kind regards

Steve

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-11-02