Try   HackMD

CURL and DNS resolver

The common question in curl is
why my browser, dig and wget work except curl.
the error message looks like this

$ curl https://github.com
curl: (6) Could not resolve host: github.com

Possilbe file and function

curl_resolver_getaddrinfo

https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/asyn-thread.c

Build curl from source

Use autoconf, then got an error

# apt install autoconf

curl# autoconf
configure.ac:22: error: possibly undefined macro: dnl
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
configure.ac:41: error: possibly undefined macro: AM_MAINTAINER_MODE
configure.ac:93: error: possibly undefined macro: AC_MSG_RESULT
configure.ac:316: error: possibly undefined macro: AM_CONDITIONAL
configure.ac:522: error: possibly undefined macro: AC_DEFINE

intall automake libtool
reference:

apt install  automake libtool

$ autoconf          # pass
$ ls configure
configure

After configuring, I got following errors:

# ./configure
./configure: line 2604: XC_OVR_ZZ50: command not found
./configure: line 2605: XC_OVR_ZZ60: command not found
./configure: line 2606: CURL_OVERRIDE_AUTOCONF: command not found
./configure: line 2614: AM_MAINTAINER_MODE: command not found
./configure: line 2617: CURL_CHECK_OPTION_DEBUG: command not found
./configure: line 2618: CURL_CHECK_OPTION_OPTIMIZE: command not found
./configure: line 2619: CURL_CHECK_OPTION_WARNINGS: command not found
./configure: line 2620: CURL_CHECK_OPTION_WERROR: command not found
./configure: line 2621: CURL_CHECK_OPTION_CURLDEBUG: command not found
./configure: line 2622: CURL_CHECK_OPTION_SYMBOL_HIDING: command not found
./configure: line 2623: CURL_CHECK_OPTION_ARES: command not found
./configure: line 2624: CURL_CHECK_OPTION_RT: command not found
./configure: line 2625: CURL_CHECK_OPTION_ECH: command not found
./configure: line 2627: XC_CHECK_PATH_SEPARATOR: command not found
checking for sed... /usr/bin/sed
checking for grep... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ar... /usr/bin/ar
./configure: line 2900: XC_CHECK_PROG_CC: command not found
./configure: line 2902: CURL_COVERAGE: command not found
./configure: line 2904: XC_AUTOMAKE: command not found
checking curl version... 7.80.0-DEV
configure: error: select TLS backend(s) or disable TLS with --without-ssl.

run configure with without-ssl, then got another error

# ./configure --without-ssl

./configure: line 2604: XC_OVR_ZZ50: command not found
./configure: line 2605: XC_OVR_ZZ60: command not found
./configure: line 2606: CURL_OVERRIDE_AUTOCONF: command not found
./configure: line 2614: AM_MAINTAINER_MODE: command not found
./configure: line 2617: CURL_CHECK_OPTION_DEBUG: command not found
./configure: line 2618: CURL_CHECK_OPTION_OPTIMIZE: command not found
./configure: line 2619: CURL_CHECK_OPTION_WARNINGS: command not found
./configure: line 2620: CURL_CHECK_OPTION_WERROR: command not found
./configure: line 2621: CURL_CHECK_OPTION_CURLDEBUG: command not found
./configure: line 2622: CURL_CHECK_OPTION_SYMBOL_HIDING: command not found
./configure: line 2623: CURL_CHECK_OPTION_ARES: command not found
./configure: line 2624: CURL_CHECK_OPTION_RT: command not found
./configure: line 2625: CURL_CHECK_OPTION_ECH: command not found
./configure: line 2627: XC_CHECK_PATH_SEPARATOR: command not found
checking for sed... /usr/bin/sed
checking for grep... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ar... /usr/bin/ar
./configure: line 2900: XC_CHECK_PROG_CC: command not found
./configure: line 2902: CURL_COVERAGE: command not found
./configure: line 2904: XC_AUTOMAKE: command not found
checking curl version... 7.80.0-DEV
configure: error: cannot find install-sh, install.sh, or shtool in "." "./.." "./../.."

Found answer here
https://askubuntu.com/questions/27677/cannot-find-install-sh-install-sh-or-shtool-in-ac-aux?ssl_
let autoreconf install package for you

$ autoconf -i
$ configure
...
...  processing

$ make

re-run with debug symbol

./configure --without-ssl --enable-debug
make
make install

run gdb with curl

~/curl# gdb -q /usr/local/bin/curl
Reading symbols from /usr/local/bin/curl...
(gdb)

curl loads lib after running it, so set the first breakpoint on curl_easy_init.
After running it, you're able to set breakpoint in any function in curl .

(gdb) info breakpoint
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00007ffff7f03fa8 in curl_easy_init at easy.c:290
	breakpoint already hit 4 times
2       breakpoint     keep y   0x00007ffff7ef1a92 in Curl_resolver_is_resolved at asyn-thread.c:569
3       breakpoint     keep y   0x00007ffff7f69702 in resolve_server at url.c:3327
	breakpoint already hit 1 time

resovler breakpoint

Breakpoint 3, resolve_server (data=0x7ffff7f56d23 <Curl_speedinit+44>, conn=0x693c48, async=0x7fff00035757) at url.c:3327

this might be the place where curl resolve the url
https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/url.c#L3305

from here we can see Curl_resolv_timeout is the function to handle resolver
https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/url.c#L3378

resolve_server
  |
  ---> Curl_resolv_timeout
         |
         ---> Curl_resolv
           |
           ---> Curl_getaddrinfo
             |
             ---> Curl_resolver_getaddrinfo
                  https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/asyn-thread.c#L691
                    |
                    --> init_resolve_thread
                    https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/asyn-thread.c#L430
                       |
                       --> getaddrinfo_thread (Run this one)
                      |    https://github.com/curl/curl/blob/fe7b64228d553274f780ebc98a05a9ae266df828/lib/asyn-thread.c#L463
                              |
                              -> Curl_getaddrinfo_ex
                                    |
                                    -> getaddrinfo(glibc lib)
                      |
                      --> gethostbyname_thread

getaddrinfo returned -2 then curl return host cannot be resovled.