cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: no custom read() write() callbacks

From: Leon Winter <lwi_at_ring0.de>
Date: Mon, 25 Oct 2010 02:27:21 +0200

Hi,

I just took a deep look at the sources of CURL to get a better
understanding of the inner workings.

> I've tried to come up with anything that would allow this in a
> somewhat reasonable way, and I can only think of two ways to do this:
>
> A)
>
> The one I prefer:
>
> > there is an example shipped with libssh2 that sets up SSH TCP
> > forwarding and listens on a local socket for raw TCP. So we could
> > use CURLOPT_OPENSOCKETFUNCTION to fire up new TCP channels and open
> > up local ports. This solution would be pretty cheap and would not
> > require modifications to libcurl but would come with overhead for
> > establishing and maintaining our fake tcp sockets. Additionally we
> > bind lots of local ports which we would not need if we could do it
> > the direct way.
>
> This is the easiest way as neither libcurl nor libssh2 need to be
> modified.

To sum up, approach A) is easier to implement, leaves both the libs
untouched but on the other hand has side effects (open local ports) and
does not use SSH handling already implemented in CURL.

> The alternative approach B:
>
> Implement this functionality natively within libcurl so that it knows
> how to setup a SSH connection to send the traffic through. This means
> quite some work and it is also a somewhat odd feature that I would
> not like to add to the const of getting more conplicated code.

In my understanding CURL does things the following way:

_easy_perform() -> curl_perform() -> curl_do_perform() ->
connect_host() -> curl_connect() -> (1) create_conn() + (2)
ConnectPlease()

If we have provided a proxy via setopt, (1) create_conn() will return a
socket pointing at our proxy host (not the real remote target). Also
eventually initialization is done (2).

We could use this way to set up SSH "proxies".
(3) create_conn() would open TCP channels on an existing SSH connection
and save it internally.

For special protocols, CURL also changes the internal send/recv
function (for SSL/TLS e.g.). This way the protocol specific send/recv
is called (lib/send.f:254).

Since SSH "proxying" is just an encryption layer we could
handle it like SSL/TLS and therefore change the internal
Curl_send/Curl_recv functions to our custom
libssh2_channel_write/libssh2_channel_read wrappers. This is pretty
similar to what CURL does for SCP/SFTP.

Normally the procotol would eventually change the recv/send functions
and a proxy would replace the socket, but for this special problem a
proxy setting would change both.

Unfortunately there are several disadvantages:
- What about HTTPS over SSH then? -> recv/send would have been
  already replaced and CURL does not allow multiple (encryption)
  protocol layers
- Like you pointed out, a very special problem that might increase
  complexity causing no benefit to most users
- Would use existing CURL infrastructe not the way it was intended too
  (replacing recv/send by a encrypted proxying layer)

The real problem outlined here is the two assumptions made in the design
process of CURL:
- When proxying connections, we just connect to the proxy host and
  exchanges proxy header stuff, the sending/receiving stuff remains the
  same.
- Protocols may add encryption (and therefore change recv/send). A proxy
  does not add encryption whatsoever.

This assumptions are reasonable and simplify handling of connections. A
more generic approach would not make such assumptions resulting in a
more complex implementation.

To put it in a nutshell, CURL was not designed for this purpose but
could eventually be abused for it. If we take in account, that there is
a plan (A as you called it) that would not do such evil things but is
easy to accompilish, I should probably take the easy road ;)

Regards,
Leon Winter
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2010-10-25