zts_py_send() was using strlen() to determine the length of the
send(). This works fine with strings, but fails with binary
data.
To fix this, I have removed the string encoding code, and
converted to using the Buffer protocol as is done in the
Python socketmodule send() implementation. This does mean
that this send() implementation only takes byte-like objects.
The workaround for this could be at the python level rather
than the C++ level.
NOTE: This implementation has a bug in the exception handling
if a non-bytes-like object is passed. You get an exception,
but the exception is not accurate, it reports the TypeError,
but the actual raised exception is due to there being a return
value when the error indicator is set. I spent a few hours
trying to fix this but was unable to. I'm afraid I just couldn't
figure it out.
My SSH proxy was misbehaving because the second block
of data going from the client to the server had a NUL byte as
the first byte to send, so the send was returning 0 bytes
sent, but that was due to send() being told to send 0 bytes.
With this, my SSH proxy is now working, including able to run
an rsync of my boot initrd over SSH over ZeroTier entirely in
userspace.
There were some bugs in my blocking code that are fixed in this.
I had the setblocking() flag reversed, and wasn't passing the
flag along to the underlying code properly.
Many changes were based on conventions in the Python socketmodule.
Changed many of the docstrings to match the Python socket library
conventions and enhancing them. I can either remove the prototype
part or add it to other docstrings in the library, depending on
feedback I get.
Changed setblocking to use the flag argument instead of always
just setting NONBLOCK.
Added enable/disable threading around more lwip calls.
Implementing optional backlog on listen().
Removing a few seemingly unneeded Py_INCREF(Py_None) calls.
Moved getblocking function based on alpha sorting of names.