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
