изменение CURLOPT_RESOLVE в libcurl - PullRequest
0 голосов
/ 01 марта 2019

Пожалуйста, рассмотрите этот фрагмент кода, мне нужно руководство по изменению CURLOPT_RESOLVE в libcurl

//snip
#include <curl/curl.h>
#include "myown_dns_client.h"

//just curly things
CURL *hnd;
struct MemoryStruct {
  char *memory;
  size_t size;
};
CURLcode res;
struct curl_slist *slist1 = NULL;
struct MemoryStruct chunk;
//just curly things


int main(){
    //snip//
    return 0;
}

void setup_curl(){
        curl_global_init(CURL_GLOBAL_ALL);
        chunk.memory = NULL;
        chunk.size = 0;

        hnd = curl_easy_init();
        curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(hnd, CURLOPT_WRITEDATA, (void *)&chunk);

        if (get_address_from_lookup() ==0){
                // we have updated slist which looks like dns.google.com:443:172.217.14.206
                slist1 = curl_slist_append(NULL, slist);
                curl_easy_setopt(hnd, CURLOPT_RESOLVE,slist1);
                printf(" ** %d Updating slist to %s\n", getpid(), slist);
        }

}

Позже в потоке update_slist, если dns.google.com начнет переходить к новомускажем, адрес 216.58.193.78, я бы хотел изменить параметр CURLOPT_RESOLVE.(Таким образом, мы начинаем отправлять запросы на этот новый адрес.)

void *update_slist(void *vargp){
        curl_slist_free_all(slist1);
        struct curl_slist *slist1 = NULL;
        // slist now contains "dns.google.com:443:216.58.193.78"
        slist1 = curl_slist_append(NULL, slist);
       curl_easy_setopt(hnd, CURLOPT_RESOLVE,slist1);
}

Не уверен, является ли это правильным подходом для изменения CURLOPT_RESOLVE.Несмотря на новый slist1, я вижу в netstat -pant, что я все еще иду на начальный адрес, а не на новый.

Любой совет будет принята с благодарностью, спасибо!

Изменить 1

#include <stdio.h>
#include <curl/curl.h>

CURL *curl;
struct curl_slist *host = NULL;
struct curl_slist *temp = NULL;
CURLcode res;
char text[8192];
FILE *popener;

void show_netstat();

int main(){

    char url[] = "https://dns.google.com/resolve?name=www.hulu.com&type=1";

    curl = curl_easy_init();
    host = curl_slist_append(NULL, "dns.google.com:443:172.217.14.206");
    curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
    curl_easy_setopt(curl, CURLOPT_URL, url);

    res = curl_easy_perform(curl);
    show_netstat();
        if(res != CURLE_OK){
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
      }


    puts("\nNEXT!");
    temp = curl_slist_append(NULL, "dns.google.com:443:216.58.193.78");
    curl_easy_setopt(curl, CURLOPT_RESOLVE, temp);
    curl_easy_setopt(curl, CURLOPT_URL, url);

    res = curl_easy_perform(curl);
    show_netstat();
        if(res != CURLE_OK){
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
      }


    puts("\nDONE!");
    curl_easy_cleanup(curl);
    curl_slist_free_all(host);

    return 0;
}


void show_netstat(){
    popener = popen("netstat -pant 2>/dev/null |grep 443","r");
    fgets(text,8192, popener);
    printf("\n----------------- ------------------- ---------------");
    printf("\n%s", text);
    printf("----------------- ------------------- ---------------\n");
    fclose(popener);
}

ngrep o / p

T 192.168.1.10:53872 -> 172.217.14.206:443 [AP]
T 172.217.14.206:443 -> 192.168.1.10:53872 [A]
T 172.217.14.206:443 -> 192.168.1.10:53872 [A]
T 172.217.14.206:443 -> 192.168.1.10:53872 [AP]
T 192.168.1.10:53872 -> 172.217.14.206:443 [AP]
T 172.217.14.206:443 -> 192.168.1.10:53872 [AP]
T 192.168.1.10:53872 -> 172.217.14.206:443 [AP]
T 172.217.14.206:443 -> 192.168.1.10:53872 [AP]
T 172.217.14.206:443 -> 192.168.1.10:53872 [AP]
T 192.168.1.10:53872 -> 172.217.14.206:443 [AP]
T 172.217.14.206:443 -> 192.168.1.10:53872 [AP] 

Редактировать 2

Niether выполняет эту работу:

#include <stdio.h>
#include <curl/curl.h>

CURL *curl;
struct curl_slist *host = NULL;
CURLcode res;


int main(){

    char url[] = "https://dns.google.com/resolve?name=www.hulu.com&type=1";
    curl = curl_easy_init();

    curl_easy_setopt(curl, CURLOPT_URL, url);
    host = curl_slist_append(NULL, "dns.google.com:443:172.217.14.206");
    curl_easy_setopt(curl, CURLOPT_RESOLVE, host);

    res = curl_easy_perform(curl);
        if(res != CURLE_OK){
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
      }

    puts("\nNEXT!");
    sleep(3);

        host = curl_slist_append(host, "-dns.google.com:443");
        host = curl_slist_append(host, "dns.google.com:443:216.58.193.78");
        curl_easy_setopt(curl, CURLOPT_RESOLVE, host);

    res = curl_easy_perform(curl);

        if(res != CURLE_OK){
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
      }


    puts("\nDONE!");
    curl_easy_cleanup(curl);
    curl_slist_free_all(host);

    return 0;
}

1 Ответ

0 голосов
/ 02 марта 2019

Вы действительно можете переопределить ранее установленную запись CURLOPT_RESOLVE, установив новую для точно такого же хоста + порта, или вы можете очистить ранее установленную запись, передав строку как -[host]:[port] (т.е. начиная с тиреи без завершающего :[address]).

Простое установление значения в NULL означает, что нет новой записи для передачи, что заставит ручку curl сохранять данные, уже предварительно заполненные ранее.

Это задокументировано на справочной странице CURLOPT_RESOLVE .

Замечание о повторном использовании соединения

libcurl будет пытаться использовать ранее использованные соединения, насколько это возможно, если вы не скажете этоиначе.Если вы сделаете второй запрос к тому же имени хоста, которое вы использовали ранее, то это соединение будет затем повторно использовано, и новая настройка CURLOPT_RESOLVE может затем не использоваться или проверяться.

Если вы хотите сделать это действительноУбедитесь, что ваш второй запрос на самом деле использует обновленный адрес, вы должны убедиться, что во второй передаче не используется соединение, которое остается в силе после первой передачи.Вы можете достичь этого, установив CURLOPT_FORBID_REUSE для первого соединения или установив CURLOPT_FRESH_CONNECT для второго.

...