Hi Martin, On Fri, Nov 21, 2014 at 12:24 PM, Martin Sustrik <sustrik@xxxxxxxxxx> wrote: > >>> You mean expensive in terms of bytes transferred? If so, fair enough. >>> >>> However, most arguments against multiple connections don't really stand. >>> I've written a blog about that in the past: http://250bpm.com/blog:18 >>> >> >> Not exactly in terms of bytes transferred. It's ok to open any number >> of connections between two services, even if they speak websockets. >> But with browsers: >> >> 1. The tend to have limits on number of connections (you can have few >> tens of services behind a single gateway, and user having 50-100 tabs >> is not so uncommon). > > > That's ugly. So there's an artificial limit on number of connections that > forces us to replace time-tested TCP multiplexing with some kind of hack of > our own for no good reason, no performance improvement or such. > Yes. That the reality all web developers live in. There is also ongoing standard that does that: http://www.ietf.org/archive/id/draft-ietf-hybi-websocket-multiplexing-11.txt Propbably there is more recent version somewhere. Or the problem is going to be solved by HTTP 2.0. I'm not following that trend very well. >> 2. Websocket connections are usually pinged to keep them closed fast >> in case of closing client connection, so traffic is huge >> >> 3. Allowing lots of connections per host make server easy DoS attacked >> (remember NAT'd clients) >> >> 4. Some companies have hundreds of employees behind NAT, so can easily >> exhaust number of ports at client-side > > > I wonder what's the conclusion from 2,3,4? To not use websockets and rather > use raw TCP services spread over multiple ports? > For machine to machine communication, yes. It doesn't matter too much whether Websocket delimits messages or some other protocol. Except websocket have mandatory "masking" and crappy handshake which are weird, but technically doesn't matter. For browser to server communication the solution is per-message multiplexing/tunelling. >> It's not weak. It prevents a javascript on web page >> http://malicious.attacker/ to connect websocket to http://gmail.com >> with your credentials. >> So yes, it's not check against bots. It's check against javascript on >> malicious web pages. > > > Right, some kind of whitelisting the origins can be added then. > Yes. And whitelist may be different for each url, if you allow multiple different services to attach to different urls at same host-port. >>> I am wondering about what the alernative would be. Any ideas? >>> >> >> The gateway, which does access auth checks and some sort of tunelling. >> It's kinda tcpmux on steroids. But, firstly to have some real >> authentication and for tunelling, the gateway must read and understand >> websocket packets itself >> >> If the gateway does packet-based routing, it may (I would argue it >> should) just prefix packet with authentication info and send that >> packet over persistent nanomsg connection. I.e. you shouldn't have >> nanomsg connection per websocket connection, but a persistent nanomsg >> connection between service and gateway. >> >> So it may be an nginx module, or standalone http/websockets server >> like zerogw or mongrel, but not a small and transparent one like >> tcpmuxd. > > > Ok, so there are 2 concerns, tunnelling and more rigorous initial > handshaking, right. > > I am still not convinced about the former (see above). > > As for the latter, can ZeroGW be re-purposed to act as a WebSocket > multiplexer; i.e. can it, after doing the initial handshake, pass the > connection to the application, the way that tcpmuxd does? > First issue, is that you still can't know which connection message comes from. And that's insecure in browser. The simplest case to explain, is if one uses client certificates to authenticate client connections. By the way how passing connection to the application is going to work with wss:// anyway? I don't think there is a TLS implementation that can serialize state and send it along with SCM_RIGHTS message. Second, I believe it's architecturally wrong. Let's consider we have a simple websock-mux M and a service S. On the same box, so connection hand off with SCM_RIGHTS work (with square brackets denoting box): Client -> [ M -> S ] The if service is too slow, to be done on the same machine, we need to move service S to a separate box(es). We do that by putting intermediate proxy: C -> [ M -> P ] -> [ S ] Now, how the proxy is going to be implemented? It can't handoff connection to a different machine. It can either create a connection to S for each client C. So number of connections C -> P between clients and proxy equals to the number of connections P -> S between proxy and service. But that the *old*, pre-zeromq way (i.e we could just put haproxy or nginx there). The *new* way is to create a single nanomsg socket P -> S between a proxy and service. But this way we need to rewrite service S when we start to scale. So why not start with the following scheme, so we can scale out later: C -> [ M -> P -> S ] Then I don't see a reason of not merging M and P. They can't be on separate boxes anyway, and they tied to a single protocol (i.e. muxer can't accept websocket where proxy expects raw tcp). -- Paul