
@mflatt Both ssl-accept
https://docs.racket-lang.org/openssl/index.html#%28def._%28%28lib._openssl%2Fmain..rkt%29._ssl-accept%29%29 and ports->ssl-ports
https://docs.racket-lang.org/openssl/index.html#%28def._%28%28lib._openssl%2Fmain..rkt%29._ports-~3essl-ports%29%29 have this same note:
> See also ssl-connect
about the limitations of reading and writing to an SSL connection (i.e., one direction at a time).
But, ssl-connect
https://docs.racket-lang.org/openssl/index.html#%28def._%28%28lib._openssl%2Fmain..rkt%29._ssl-connect%29%29 doesn’t seem to discuss this AFAICT.
Maybe the limitation was resolved and the ssl-connect
doc got updated — and it’s just the “see also” notes needed to be deleted but weren’t? Or, is there some discussion that needs to be added to ssl-connect
?

Yes, I think that note is referring to a limitation that was removed.

Thanks. That makes sense given my limited understanding of the mzssl.rkt
code I looked at. It seems to be doing an awful lot of work to handle openssl where you want to write, but it needs to read, presumably during the handshake phase but idk really. So maybe that work was to remove the limitation.

@mflatt While I have you. I tried using ports->ssl-ports
to “upgrade” a Racket pipe. The other end of the pipe is talking to UDP. I’m seeing the throughput get about 8X slower, which doesn’t seem right. The CPU usage isn’t super high, for instance. So it feels like something is blocking longer than it needs to… but I’m not really sure. I’m still trying to understand what’s happening, and unfortunately don’t have simple example code to share (yet). But I wanted to mention it in case it tickled something, some general advice to look at X, you might have? If not of course no worries and sorry to distract you!

Maybe buffering? Looking breifly at the implementation of SSL output ports, I don’t see a buffer for writes. Every individual write seems to go to SSL_write
.

OK thank you, I’ll think on that.

@mflatt Did you mean, my app should try to write in bigger chunks to the TLS output-port, or, the implementation in mzssl.rkt would need to change? I ask b/c a single write-bytes
many many bytes still elicits this. Also it seems like gc is 40–60% of the real time, depending on OS. Simple example, with timings in comments at the end: https://gist.github.com/greghendershott/c610fc2e6f74466a5e0d198115d6e5d2

(That example is just the TLS ports wrapping pipes — like from one of the tests I noticed. Nothing to-do with UDP or whatever else.)

I can see why that example goes disasterously wrong. The output port has a buffer of 8000, so it’s writing 8000 of the N bytes passed by write
, and then write
ends up copying N–8000 bytes for the next request, and so on, which makes it quadratic.

Sorry about adding more noise to the channel, while troubleshooting the missing libcrypto.so
issue when using racket on a TrueOS system which is a FreeBSD variant using LibreSSL, I ran into an entirely new problem after successfully resolving the libcrypto.so
issue. The error every time I try to install a package is now telling me tcp-write: error writing system error: Socket is not connected; errno=57
This error is the same one as reported in https://github.com/racket/racket/issues/1812
Not sure if this is possibly a bug in LIbreSSL, don’t know how to start debugging this. I’m seeing if there are any LibreSSL environment variables that could help to print more details

Chunks much smaller than 8000, meanwhile, will be individually flushed. But maybe the SSL layer has its own buffering, because I don’t see much difference in relative performance between 7000 bytes and 70 bytes.

Oh, one write isn’t going to be a good comparison…

The gap does seem to narrow with 70 versus 700 written 1000 times, but it doesn’t close much.

So, it looks like the overhead of make-output-port
is larger than the buffering effect.

@abmclin can you try 6.9, which that report says works?

I found the download for the 6.9 source code, will compile and report back

@abmclin Did you solve the problem you had yesterday (or is it the same one)

@soegaard2 yes the problem I had yesterday have been solved, by adding appropriate entry to the versions list in libcrypto.rkt

I now have an entirely new problem, if 6.9 works then it should be possible to compare the relevant code between 6.9 and 7.2 to see what changed

Ok.

Hmm OK it looks like writing in smaller chunks (< 8000) does make the TLS version be only 20X instead of 100X slower.

I don’t have a good intuition for how much slower it “should” be, except reading things about how using TLS only uses single digit % more CPU when Google did it. Which is handy-wavy.

@abmclin there are binaries for 6.9 here: https://download.racket-lang.org/racket-v6.9.html

To me, make-{output input}-port
seems kind of scary and complicated; I feel I’d get it wrong. I’d probably try to use pipes. Even if that would work (?), would it be less performant?

@samth I can verify that 6.9 works while 6.10 fails with the socket not connected error, looking at 6.10 announcements, I see that it was in 6.10 when the new rktio layer came into use so I suspect that’s where the failure can be narrowed down

At this point probably @mflatt needs to suggest further debugging steps.

I don’t know. The longer-term solution may be an unsafe API for implementing lower-overhead ports.

Do you get the same error with just (define-values (i o) (tcp-connect "<http://pkgs.racket-lang.org\|pkgs.racket-lang.org>" 443))
(write-byte 0 o)

May need a (flush-output o)
.

I ran the above under 7.2 and it returns
tcp-write: error writing
system error: Socket is not connected; errno=57

Does it make any difference to add # define USE_FNDELAY_O_NONBLOCK
to the FreeBSD section of “rktio_platform.h”?