cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: CURLOPT_CONNECT_ONLY doesn't seem to work

From: Nico Williams <nico_at_cryptonector.com>
Date: Tue, 4 Jun 2013 22:39:11 -0500

On Tue, Jun 4, 2013 at 10:33 AM, Daniel Stenberg <daniel_at_haxx.se> wrote:
> On Tue, 4 Jun 2013, Nico Williams wrote:

> "evidently" ?

I shouldn't have posted at that hour :( (sorry). I now have a program
that gets further.

> Can you start with clearly telling us what "doesn't work" mean?

Let's start with what I'm after: a netcat-like program that connects
stdin/stdout to some host:port via an HTTP proxy using CONNECT.

There exist a number of such programs, but none (that I can find) that support
Negotiate. Libcurl does support Negotiate, so I'd rather use it.

My program currently does all of this:

 - sets CURLOPT_URL, CURLOPT_PROXY, CURLOPT_PROXYAUTH, CURLOPT_PROXYUSERPWD,
   CURLOPT_HTTPPROXYTUNNEL, and CURLOPT_CONNECT_ONLY

 - also sets CURLOPT_VERBOSE

 - calls curl_easy_perform() and gets CURLE_OK

 - calls curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sock) to get a
   socket on which to poll

 - enters an event loop to copy data from the proxy to stdout and from
   stdin to the proxy; writes to the proxy are done via curl_easy_send()
   and reads from it are done via curl_easy_recv().

I'm able to curl_easy_send() once, but curl_easy_recv() generally fails
with CURLE_UNSUPPORTED_PROTOCOL.

[The CURLE_UNSUPPORTED_PROTOCOL case comes from getting a FIN on the
 socket from the proxy (recv(2) returns 0), which causes
 Curl_getconnectinfo() to return CURL_SOCKET_BAD. This seems spurious:
 since we had EOF curl_easy_recv() should return CURLE_OK and indicate
 that zero bytes were received, per its manpage.
 If I remove the #ifdef MSG_PEEK code in lib/connect.c I get CURLE_OK
 and zero bytes on EOF, which seems much better.]

The curl(1) command manages to read from the CONNECT. (It also insists
of doing an HTTP GET, which I don't want, but at least I can see that
curl(1) manages to talk to the remote server via the proxy.)

Why am I getting EOF when curl(1) is able to read from that socket?

If I run: "curl -v --proxytunnel foo:22" then I actually get an SSH
version string from the server, but I don't get that in my program from
curl_easy_recv() when connecting to the same host.

In both cases (my program and curl(1)) I see that the CONNECT succeeds
("< HTTP/1.1 200 Connection established", preceded by the Negotiate
noise), so I'm at a loss as to why curl(1) gets to read the ssh version
string from the server but my program using curl_easy_recv() doesn't.

This program is rather straightforward, and is based on
docs/examples/sendrecv.c, you can find it here:
https://raw.github.com/nicowilliams/curltunnel/master/curltunnel.c (or
clone it from https://github.com/nicowilliams/curltunnel). What am I
doing wrong?

Nico

--
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
Received on 2013-06-05