1

I've just discovered the existence of sslh.

I tried to install it on my 512MB RAM VPS running Debian 7 wheezy. After having configured sslh, I tried to connect to one of my apache2 virtual hosts, and immediately the cpu usage went up to 50-60%, even ssh-ing the VPS was almost impossible due to the lack of resources.

  • Is this normal?
  • Is there any valid alternative?

The problem I was trying to solve using sslh is that many free wifi hotspots block almost every port, except 80 and 443, and I often need to use OpenVPN to connect to my home server, which is natted by my ISP.

Do you have any other solution to suggest?

7

From a casual review of the source, it appears the author(s) were overzealous in their use of set_nonblock in sslh-select.c.

If you flag every socket (as it does) as non-blocking, the the loop

while(1) {
    select(… a bunch of non-blocking sockets …);
}

at around line 230 in the linked file becomes a busy-wait. That is, even if there is no data available to read on any socket, select returns instantly and then gets called again immediately. This is rather processor intensive.

The author came close to getting it right, with some conditional use of the timeout argument to select but that has no effect if all are set to non-blocking anyway.

I didn't profile sslh which is he best way to confirm this is the real cause.

  • That was a very exhaustive answer! Could you please suggest an alternative that is not so processor intensive to solve my problem? I found sshttp, do you think it will be so demanding of resources? Thank you. – giovi321 Jul 8 '14 at 14:50
  • The problem with sslh is an outright bug. I find it hard to believe that another program like sshttp would make the same mistake. Unfortunately, I have no interest in benchmarking port multiplexors; good luck. – msw Jul 8 '14 at 18:26
3

So this issue is now followed here: https://github.com/yrutschle/sslh/issues/24

msw's answer might be exhaustive, but is also wrong: select() will block regardless of the socket's O_NONBLOCK status, that's basically what it's there for, and in fact code that uses blocking sockets when using select() is wrong. From Linux' select(2): "Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks".

In other words, not setting O_NONBLOCK while using select() may result in complete blockage of the program.

So, while something might be wrong, this is not it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.