Hi, So this topic is interesting for me again after quite a long time ;)
Short reminder of the topic: Using CURL for HTTP operations using SSH tunneled TCP connections set up by libssh2. > > Good point again, we could indeed use CURLOPT_OPENSOCKETFUNCTION > > along with CURLOPT_SOCKOPTDATA to pass our e.g. ssh channel. > > However there is no "socket close function callback" atm but also i > > macro sclose(). Since we are going to replace sread()/swrite() with > > callbacks, we should probably to that with sclose() too. > > Yeah, I think so too. > > > Hopefully I havent missed something again ;) > > I think the best way forward from this point is to actually proceed > and try to write your application and then see what kind of hooks > libcurl needs to offer for it to work, and do some first basic shots > at implementing them to see that the app lives. In lib/connect.c, at line 842 the socket is setup by our custom fopensocket (which is set beforehand via CURLOPT_OPENSOCKETFUNCTION) and therefore it is assumed a normale socket is returned (this is also required by specification for CURLOPT_OPENSOCKETFUNCTION). (1) Therefore operations are done on this socket pointer like tcpnodelay(), nosigpipe(), Curl_sndbufset() and verifyconnect(). When using libssh2 to setup a TCP channel we however does not have a standard socket interface. We could save the raw socket which is used for SSH operations and return it in CURLOPT_OPENSOCKETFUNCTION, but this is probably not a good idea, since libcurl assume its the real socket read/write operations take place - which it is not. For further operations like read()/write() we will not use the raw socket but the libssh2 channel, so it would be more reasonable to save LIBSSH2_CHANNEL* instead of the channel struct, but we cannot return it via CURLOPT_OPENSOCKETFUNCTION since a socket is expected to be returned. So now I am trying to figure out a sane approach to solve this things. Unfortunately I am new to the libcurl codebase and hope for feedback. My thoughts so far: A new CURLoption "CURLOPT_SOCKPTR" which is a void* and point to our libssh2 channel (or probably something else useful in the future). The CURL easy code then checks CURLOPT_SOCKPTR. If is not set (== NULL) it assumes its does things the normal way (like its done at the time). If its set, no socket modifying functions are called on the socket, like the ones in (1). Additionally we need new CURLoption callbacks: - CURLOPT_READSOCKFUNCTION - CURLOPT_WRITESOCKFUNCTION - CURLOPT_CLOSESOCKFUNCTION Which should fit fine to the already existing: - CURLOPT_OPENSOCKETFUNCTION The read()/write()/close() replacements will operate on the libssh2 channel saved in CURLOPT_SOCKPTR and the real sockfd (which is returned by CURLOPT_OPENSOCKETFUNCTION) is never touched by CURL. The weaknesses of this approach are: - it is not really generic and awesome - the internal socket pointer is never used (it is however intended to point to the socket that should be used), therefore we will need a lot of conditional checking for performing socket operations which is pretty bad - at the moment this approach will not use any of CURLs libssh2 integration, which also provide nice handling for fingerprint matching and stuff On another note, 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. Regards, Leon Winter ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
