Fresh off the press is version 3! I've changed quite a few things under the hood of PTssh and hopefully this will make PTssh much more robust and easier to use. The big change that's likely to effect people the most is the C API has changed. Now all C functions are preceded with "ptssh_" to help avoid function collisions when using PTssh as a .DLL or .SO
Changelog for 0.3.0 alpha
-Updated the C API to prepend all function calls with "ptssh_". This more closely follows most C style libs and should also help keep function naming collisions low. Thanks to Joe M. for pointing this out.
-Fixed a problem where the SocketSend thread would make CPU usage spike every now and then even if there wasn't anything waiting to be sent.
-Fixed a potential threading problem in the SftpRequestMgr class. This could potentially let one thread add or remove a Sftp request while another was looking up a Sftp request and then end up looking at the wrong request because of the first thead adding/removing a sftp request in the list at just the right moment.
-Fixed the restriction on having a maximum number of Sftp requests. You can now make as many sftp requests simultaneously as your system can handle.
-Fixed an issue with shutting down PTssh where the SocketSend and/or SocketRecieve threads would not shutdown properly and could cause a deadlock. The thread shutdown logic was re-written, the original stuff was crappy.
-Fixed an issue with SocketSend and SocketRecieve threads not properly detecting and handling socket disconnection or dropped connections.
-Fixed several build problems due to some missing #defines
-Removed the usage of the Select() function call. PTssh now does not need the select function.
-Added disconnect callback support. PTssh can now let the end-developer register a function callback that gets called if the socket goes down or gets dropped. The developer can also store a pointer such that it will be available when the callback occurs, PTssh holds it as a void* in its CallbackData struct.
-Use of the PTSSH_ENABLE_LOGGING macro is now fully supported: Added the PTLOG macro. Using PTLOG instead of ptLog will let us compile in or out all logging messages. This will help PTssh have a much smaller footprint on embedded systems, or allow developers to completely disable PTssh's debugging messages. If you comment out the PTSSH_ENABLE_LOGGING #define, all of PTssh's debugging messages will not be compiled into the build. Saves about 10K
-Fixed some build issues under VS2k8 with zlib enabled on the Sftp_usingClass and MultipleConnectionManager projects
After taking a step back and looking at the layout of the library compared to some others out there, I noticed that the general layout of the source and include files were not quite in the best spot. So I've restructured the project so that its more friendly to use. Include files are in their own directory and source in another. This should make it much easier for projects that use the shared library only.
Maybe one of these days I'll get some feedback. Until then, enjoy version 0.2.0 !
Just released for your enjoyment, PTssh version 0.1.0! The biggest change in this version is support for SFTP. I spent most of my development effort on getting Sftp in place. Its not completely finished, but should be extremely usable.
Changelog for 0.1.0
New Features: SFTP support!
-Added SFTP support for version 3
-Added the multiple connection manager in order to demonstrate multiple threads utilizing one PTssh object.
-Fixed an issue that would sometimes crop up when sending a SSH_DISCONNECT message that the Socket Send/Receive threads would not correctly exit. Please note that theres still a few items that I need to work on so that when errors occurs threads shut down properly. If you find your client in what appears to be a deadlocked state, you've hit one of these areas that I'll soon be looking into ;p
-Removed the need for any developers to mess with initializing the Winsock library when building on Windows. All socket stuff is now taken care of internally. The examples have all been updated to reflect this.
-Added two SFTP examples: One shows how to use the C++ class method and the other shows how to use the shared library method ( .DLL or .SO)
-The SFTP manager has a hard-coded limit of a maximum of 10 outstanding requests at a time. This will be dynamic in the next release so you can have an infinite number. Its on my TODO list!
-The value of PTSSH has changed! I've moved it to be defined to 0. This makes PTssh conform to the general return value of 0 for success that most other C libs use. IT also allows me to still use the negative numbers for errors and also be able to pass back the actual SFTP error values (these are all positive 1+)
-Fixed the PTsshConfig.h section that allows you to optimize PTssh for 1000/100/10Mbps connections. You can now enable what you want to match how you expect your code to be used in order to have best performance and memory utilization.
I've been working on some ideas for adding SFTP support into PTssh, that way it'll make the library much more complete. Plus, there's probably only a handful of people out there (like myself) that care about a good SSH library. I imagine the majority of the people that use SSH related libs use them for their SFTP support.
I'm only a little familiar with SFTP, having used it a tiny bit for random scripts and such. I must say that I do like the way that with SFTP you make requests for things. However, this also can hurt performance when doing things like trying to read a 100MB+ file down over SSH. Why? Well, you can make a request for the entire file, but more than likely, your SSH/SFTP server will only send back about 64KB at a time. I imagine that this was done so that if the user make a SFTP request to read a 1gig file, that they don't have to wait on the entire file to transfer before being able to make more requests. And for that, its a good design...
Seems that SFTP ver3 has this read file limitation: You request to read a big piece, but only get as much as the Sftp server wants to send you. Seems this limitation was addressed in Sftp version 6. During the client and server handshake, the client gets a "supported2" structure, which gives details about the maximum read size.
Now here's the downside to it. If you are on a fairly quick network and you do things in a rather single-threaded serial nature, you'll have a flow thats something like this:
---> requests nth 64KB ----->
<-----gets nth 64KB ------<--
--> requests n+1th 64KB --->
< ----- gets n+1th 64KB <-----
This is HORRIBLE for efficiency sake! The latency between the client and the server becomes a huge factor in how fast a file will take to transfer. Say you want to transfer a 100MB file. With OpenSSH's sftp subsystem, you'll only get 64KB pieces at a time, so we would need to make 1,600 requests for the pieces of the file. Let's say you have a decent connections and the time to make a request and get that data (assuming request is handled instantly) is 0.1msec. This means that we will spend about 1600 x 0.5msec just waiting on requests to travel back and forth + the time required for actual data transmission. So we have a nasty overhead of 800msec ( 0.8sec). Sure this seems like a small amount of time, but it really hurts efficiency over high-speed links (1000Mbit+).
Here's some quick benchmarks that I took on some of my early SFTP code vs. the quicker SCP transfer. A setup a ramdisk on the linux box thats running OpenSSH v5.1 so that reading the file from that system wouldn't be limited or slowed down by slow hard drive reads. Reading from the ramdisk is incredibly fast ;p
Reading a 576,346,112 byte file from the linux host:
SCP average: 76MB/sec ~7.25 sec
SFTP average: 21MB/sec
Definitely room for a lot of optimization ;p
So shortly after I posted the first packaged release of PTssh, I realized that I completely forgot to mention in the README file that you need to setup your environmental variables so that PTssh can find certain things like Zlib, OpenSSL and pthreads. oops. So here's a little snippet:
Setup these env vars:
OPENSSL = c:\your\path\to\openssl\
ZLIB = c:\your\path\to\zlib
PTHREADS = c\:your\path\to\zlib
Now add the variables to your PATH variable, ex:
PATH = %SystemRoot%\system32;%SystemRoot%; ....%OPENSSL%\out32dll;%ZLIB%;%PTHREADS%\lib;
Now you may ask why in the world set an environment this way. Well, now it becomes incredibly easy to switch between different versions of OpenSSL, Zlib and pthreads by simply changing where a env. var points to. Slick eh?
So back about a year ago, I was writing a terminal application similar to PuTTy and was looking for a good SSH l ibrary to use. I happened upon two libraries that looked like they'd fit the bill: libssh2 and libssh.