I committed and pushed some changes a while ago, which I believe fixes
the issue, please get the latest git/snapshot and see how it works for
you!
there are some compile issues with git head
1) url.c "url.c:4932: error: 'struct PureInfo' has no member named 'ip'"
i just renamed ip to primary_ip. maybe you forgot to commit changes in url.c?

2) connect.c:860: error: 'sa6' undeclared
is inside #ifdef ENABLE_IPV6 i changed to
so i added +struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr;

Now my test with the easy interface do work, but not the one with the multi interface.
There the problem persists: the ip info of the reused connection is empty.
...
curl finished--------------------
lip:127.0.0.1 lport:54113 <---> rip:127.0.0.1 rport:80
multi end----------------
...
curl finished--------------------
lip: lport:0 <---> rip:127.0.0.1 rport:0
multi end----------------


I attached the code of my test program

cheers Frank
#include <stdio.h>
#include <curl/curl.h>
#include <unistd.h>

CURL *easy_handle=NULL;
CURLM *multi_handle = NULL;

void printTCPInfo(CURL *curl)
{
    char* rip = NULL;
    char* lip = NULL;
    long rport = -1;
    long lport = -1;
    curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &rip);
    curl_easy_getinfo(curl, CURLINFO_LOCAL_IP, &lip);
    curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT, &rport);
    curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT, &lport);

    printf("lip:%s lport:%ld <---> rip:%s rport:%ld\n",lip?lip:"na", lport, rip?rip:"na", rport);
}


void performEasyRequest(const char* cUrl)
{

    CURLcode res;

    if (!easy_handle)
    {
        easy_handle = curl_easy_init();
        printf("curl handle init\n");
    }
    else
    {
        curl_easy_reset(easy_handle);
    }

    if (easy_handle)
    {
        printf("easy start----------------\n");
        printf("URL:%s\n",cUrl);

        char errorBuffer[CURL_ERROR_SIZE];
        errorBuffer[0] = '\0';

        curl_easy_setopt(easy_handle, CURLOPT_ERRORBUFFER , errorBuffer);


        curl_easy_setopt(easy_handle, CURLOPT_URL, cUrl);
        res = curl_easy_perform(easy_handle);
        printf("curl finished--------------------\n");

        printf("res:%d -> \"%s\" -> \"%s\" \n",res, curl_easy_strerror(res), errorBuffer);

        printTCPInfo(easy_handle);
        printf("easy end--------------------\n");
    }
}


void performMultiRequest(const char* cUrl)
{
    if (!multi_handle)
    {
        multi_handle = curl_multi_init();
    }

    if (!easy_handle)
    {
        easy_handle = curl_easy_init();
        printf("curl handle init\n");
    }
    else
    {
        curl_easy_reset(easy_handle);
    }

    printf("multi start----------------\n");
    printf("URL:%s\n",cUrl);

    int still_running;

    curl_easy_setopt(easy_handle, CURLOPT_URL, cUrl);

    curl_multi_add_handle(multi_handle, easy_handle);

    while (CURLM_CALL_MULTI_PERFORM ==
            curl_multi_perform(multi_handle, &still_running));

    while (still_running)
    {
        struct timeval timeout;
        int rc=1; /* select() return code */

        fd_set fdread;
        fd_set fdwrite;
        fd_set fdexcep;
        int maxfd;

        FD_ZERO(&fdread);
        FD_ZERO(&fdwrite);
        FD_ZERO(&fdexcep);

        /* set a suitable timeout to play around with */
        timeout.tv_sec = 2;
        timeout.tv_usec = 0;

        /* get file descriptors from the transfers */
        curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
        /* In a real-world program you OF COURSE check the return code of the
                function calls, *and* you make sure that maxfd is bigger than -1 so
                that the call to select() below makes sense! */

        //printf("select()\n");
        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
        //printf("select() returns:%d\n",rc);

        switch (rc)
        {
        case -1:
            /* select error */
            still_running = 0;
            printf("select() returns error, this is badness\n");
            break;
        case 0:
            printf("select() timeout\n");
        default:
            /* timeout or readable/writable sockets */
            printf(".");
            fflush(NULL);
            while (CURLM_CALL_MULTI_PERFORM ==
                    curl_multi_perform(multi_handle, &still_running));
            break;
        }
    }//still running

    printf("curl finished--------------------\n");

    curl_multi_remove_handle(multi_handle, easy_handle);

    printTCPInfo(easy_handle);

    curl_easy_cleanup(easy_handle);
    easy_handle = 0;

    printf("multi end----------------\n");

}


int main(int argc, char* argv[])
{
    const char* cUrl= "127.0.0.1";
    if ( argc>1 )
    {
        cUrl=argv[1];
    }

//    performEasyRequest(cUrl);
//    performEasyRequest(cUrl);
    performMultiRequest(cUrl);
    performMultiRequest(cUrl);

    return 0;
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to