
A solution for enabling UDP in the web - vvanders
http://new.gafferongames.com/post/why_cant_i_send_udp_packets_from_a_browser/
======
techsupporter
Minor nit that I almost hesitate to pick but I've been doing 100-series
network training lately so this is something that I'd tell my students:

> UDP packets are not encrypted, so any data sent over these packets could be
> sniffed and read by an attacker, or even modified in transmit. It would be a
> massive step back for web security to create a new way for browsers to send
> unencrypted packets.

TCP packets are not encrypted, either. That data is transmitted via UDP or TCP
doesn't make it encrypted; encryption is handled elsewhere.

Now if you insist that the _contents_ of the transmitted UDP packets are
encrypted--as the author does with the documented proposal--then that's one
thing. But the data transport mechanism (UDP vs. TCP) doesn't inherently mean
encryption.

(Fun fact I learned while writing words about TLS: Use of TLS does not
automatically imply confidentiality--that is, encryption--of the data being
transported. TLS supports a NULL cipher[0] that ensures integrity and
authenticity but the payload is "in the clear.")

0 - [https://tools.ietf.org/html/rfc4785](https://tools.ietf.org/html/rfc4785)

~~~
thezilch
You're not wrong, but I think the point was, in a browser, you can get your
TCP _connection_ "automatically" encrypted by connecting to HTTPS endpoints.
It's not so easy -- "built in" \-- with a connectionless protocol.

~~~
bdonlan
There is DTLS if you really want turnkey encryption for UDP, and it's
implemented by openssl so it's straightforward enough to find an
implementation. Not the most widely deployed protocol out there, to be sure,
but if browsers wanted to make that the condition of use it would soon become
widely implemented.

~~~
thezilch
"openssl [...] straightforward" I don't think so. It's in the article; DTLS is
too complex. The author wants something simple.

Most implementations (eg. WebRTC) involve pulling in truck loads of C libs;
it's insane. And then you want to support other clients? Good luck.

------
throwawasiudy
It's kinda sad that TCP was chosen so long ago for HTTP that there's
effectively no changing it. With modern TLS the underlying data guarantees TCP
gives you just aren't that useful. We have kinda a weird situation where we
have TCP->TLS->HTTP in layers when it could all be one protocol layer. We also
wrap a stateless protocol (HTTP) inside a stateful (TCP) one which causes some
insanity.

What the problem with doing it the current way? Massive routing inefficiency
at scale. Since the layers for persistence and routing (L2-4) don't carry all
the info needed to connect to a server (some like headers and URL are up in
HTTP - L7) it's mandatory to "unwrap" through the protocol layers before you
can determine where a stream/packet/HTTP req is supposed to go.

This means you can use something like IPVS as your L2-3 load balancer, but
once the streams are divided out by IP/port you need to do the TLS+HTTP in one
step. There's also some hard limits on how much traffic a single IVPS instance
can handle because balancing TCP even at low level requires the router to keep
track of connection state (conntrack). So we have this situation where there's
a main low-level balancer with some arbitrary traffic limit imposed from TCP
overhead, and behind that we have a bunch of child balancers doing way more
work than they should be handling the connection from the TCP level through
TLS and HTTP before they can pass on the connection to a back-end app server.

This could all be avoided if HTTP was a stateless UDP based protocol, and TLS
was baked in rather than being an additional layer. It would make routing and
load balancing far more effective at scale. You probably wouldn't see nearly
as many DDoS attacks succeeding, because the vast majority of them exhaust CPU
power far before they actually flood you off the net.

~~~
cm2187
I think the question is not so much could http have used UDP, but rather is
the browser the right place to build a complex piece of software. The fact
that you can doesn't mean that you should. I am a bit concerned that the
browser is becoming the only cross platform API and we are forced to build
complex software on top of a scripting language that was only designed to fire
up porn advertisement pop ups.

~~~
__ddd__
Ignoring the (in)validity of your characterization of JS, web assembly will
remove this reliance on JS

------
just4suggest
My memory is fuzzy, but I'm pretty sure I did this with WebRTC a while ago.
Use RTCPeerConnection in unreliable mode, "peer" with the server, and you
should have a UDP-backed SCTP connection. I'll try to dig up my PoCs on this.

Edit: Oh he mentions this, but invalidates it due to the complexity of typical
P2P:

> But from a game developer point of view, all this complexity seems like dead
> weight, when STUN, ICE and TURN are completely completely unnecessary to
> communicate with dedicated servers, which have public IPs.

I don't remember this being complex (there was some off-the-shelf library for
getting a data connection on the server-side), but YMMV.

~~~
TD-Linux
That's because you don't need to implement any of those things for a basic
client-server architecture. Unfortunately it looks like the author saw the
massive and complex webrtc.org implementation and gave up, rather than try
writing their own minimal implementation, or borrow from other implementations
like Janus
([https://janus.conf.meetecho.com/textroomtest.html](https://janus.conf.meetecho.com/textroomtest.html)).

~~~
just4suggest
Yes; vaguely... there was some (string) message format that you could manually
stitch together with the right IP and port, etc, and basically tell the
browser's WebRTC implementation "other client is on this IP and port". I seem
to have deleted this code unfortunately, the only thing I saved is this link:

[https://github.com/cjb/serverless-webrtc/](https://github.com/cjb/serverless-
webrtc/)

EDIT:

Aha! I based my code on: [https://github.com/js-platform/node-
webrtc/blob/develop/exam...](https://github.com/js-platform/node-
webrtc/blob/develop/examples/bridge.js)

~~~
TD-Linux
Yup, the format is called SDP. It's an old, crufty, and mostly effective way
to specify not only the port and IP, but also whether a TCP fallback is being
used, video and audio formats, and other things you can mostly ignore when
just using data channels. See the "answer" section of 5.2.3 of [1], for
details of some of the other magic numbers (which your JS library should
handle for you). You can also check out about:webrtc to see SDPs made by other
websites, like the Janus demo page.

[1] [https://tools.ietf.org/html/draft-ietf-rtcweb-
sdp-03](https://tools.ietf.org/html/draft-ietf-rtcweb-sdp-03)

------
yokohummer7
> Websites would be able to launch DDoS attacks by coordinating UDP packet
> floods from browsers.

> New security holes would be created as JavaScript running in web pages could
> craft malicious UDP packets to probe the internals of corporate networks and
> report back over HTTPS.

Is this the same reason that the "raw" TCP is not supported on the web? When I
first learned WebSocket I was surprised that it is a message-based protocol.
What I imagined was a protocol that utilizes HTTP only as a means of
negotiation, and the actual transfer is done just as the raw TCP does. But
it's not, so I had to create another layer to be interoperable with the
existing (raw) TCP server. What was the exact reason?

Edit: Another reason I can think of is the encoding issue, cause TCP is byte-
based. But the current WebSocket spec already assumes UTF-8 for textual data,
and is also capable of sending bytes using `ArrayBuffer`. I don't see how this
would matter in practice.

~~~
Matthias247
Just a remark: You can use the websocket spec to emulate TCP behavior, which
means get a stream instead of messages: Send only one giant message (payload
set the maximum) and use Continuation frames to stream new chunks of data to
the other side. FIN will be only set once the stream has finished.

The downside: A lot of websocket APIs (and most especially the one in the
browser) don't support this and will only send/receive complete messages.
Which means if you want streaming support you better implement it as a layer
on top of messages, since it works everywhere.

It's a little bit sad that the websocket spec is complicated through the
continuation frame feature while in reality noone has a reason to use it.

And back to the question: The masking "feature" of websockets is also there to
prevent browsers from speaking raw TCP. Without it Javascript could craft
exact TCP payloads, which might in certain situations be used to directly talk
and manipulate internal services. The masking guarantees that the remote on
the TCP connection will get some random data after the websocket header.

~~~
yokohummer7
That's interesting, I've always thought the WebSocket spec is too complicated
with all those frame types and message fragmentation, and I completely ignored
contunation frames when I had to implement the protocol myself. But it seems
more versatile than I imagined. Though the workaround you mentioned sounds a
bit hacky.

And yeah, I now remember that masking was also a problem at the time. So even
if web browsers adopt a new API to send fragmented messages, it would still
not be possible to directly plug in them to legacy servers. Sad.

Edit: It would also be possible to send a single giant message, which contains
a single giant continuation frame sent for the lifetime of the session, which
is followed by a FIN frame. Am I correct?

~~~
Matthias247
Yes, you could use the single giant message too. The drawback to the
continuation frame approach is that you can't interleave it with ping frames
(for connectivity checks) and that you won't be able to signal end of stream
(FIN). If that's not required because your higher level protocol takes care of
that things otherwise it would be fine.

------
stcredzero
I am using WebRTC with a MMO server cluster written in Golang. Basically, I
got Simple-Peer WebRTC library to run on top of node-electron in NodeJS. My
Golang coordinating server then also coordinates a farm of 4 NodeJS processes
which basically run as UDP proxies. The complexity of WebRTC is tamed by
Simple-Peer.

One downside: Getting node-electron to run takes some wading through shared
library installs to satisfy Chrome dependencies. However, this turns out to be
a series of straightforward responses to error messages. Another downside: I'm
wasting some memory and swap on Chrome dependencies I'm not using. In the case
of my game, I'm always going to be more CPU/bandwidth bound than memory bound,
so this turns out to be a non-issue. A third downside: WebRTC uses up 72 bytes
of each packet with its own header information.

All that said, it appears to be running like a champ. It also makes a big
difference in the play-ability of my game in poor network conditions.

~~~
pthatcherg
Are you using the data channel p2p or client-to-server?

(I work on WebRTC and implemented much of the data channel; I'm always
interested when someone uses it)

~~~
stcredzero
Client server. I'm being extra paranoid about cheating/security, so it's a
naive client-server, authoritative server architecture. The client isn't much
more than a dumb server, but for 2D sprites, not text.

------
bborud
I think some of the ensuing discussion here says clearly why UDP in the
browser (at least as in giving developers access to firing off random UDP
packets from a browser) is a bad idea: people don't understand network
protocols, yet they feel they have something to contribute to the discussion.

------
mjevans
I'd like to focus on the security issue of 'UDP probes and sending results
back over HTTPS'. This is an /inherent security issue/ of running ANYONE
else's code within a corporate network.

ECMAscript/JavaScript should NOT be blindly run within corporate networks, and
web 2.0 is insane for making all websites expect that.

~~~
michaelvoz
Can you elaborate on this? Legitimately curious.

~~~
TheBobinator
Parasitic Companies want the ability to run anything they want, on anyone's
machine, accessing all of the users personal data, as well as their
competitors data if they can get at it, and use it for whatever reason they
want, and have the ability to secure those revenue streams by erecting wholly
artificial and socially destructive barriers to their removal, such as getting
accepted to represent their interests in standards bodies then twisting the
standards to do what they want. An example of this is EUI addresses in IPV6
with the Mac address as part of the IP address as a revenue stream
maximization method for advertisers.

There was a you tube video awhile ago showing java-script able to run an
operating system in a web browser as well as games inside the OS. Recently,
Chrome added a task manager and user logins. Chrome is no longer a web
browser, it's an operating system, and what enables an entire ecosystem of
abuse is java-script.

In a few years hence, someone will figure out a technology that will disable
java-script from running on client machines via firewall filter. It will break
a lot of websites. Let it.

~~~
Jonnax
Each tab runs in its own thread, a page consumes CPU and RAM. I'm not sure why
it's a bad thing that a web browser has a task manager. Especially since one
of the powerful things about the web is that no extra software is required for
debugging / development.

It's totally possible today to create a filter that will scan for JS and
remove it from sites with one of those man-in-the-middle corporate proxies.

But it'll break pretty much every site. If you're talking about a company,
that's as conductive to security as mandating weekly password changes
requiring no repetition, symbols, lower + upper case and 15 characters.

Users will find ways around it. Like bringing unmanaged devices to browse the
internet.

In terms of broken websites, corporate users don't have the influence as they
did in years past.

Since we're trending towards pretty much every person in more economically
developed countries having smart phones.

If a website doesn't work for a business's users I don't see how site owners
will care.

On the development of web browsers becoming an OS of their own. Sure there's
work to be done to improve security. For example, fingerprinting needs to be
properly mitigated [1].

The web is open. Anyone can implement a web browser. Chrome, Safari, Firefox,
Edge are trending towards writing one webpage/app and having it run
everywhere.

Windows, OSX, Linux, Intel, ARM, Desktop/Laptop, Mobile/Tablet. Aren't a
concern past display/formatting.

[1] [https://panopticlick.eff.org/](https://panopticlick.eff.org/)

------
api
> It falls down because WebRTC is extremely complex. This complexity is
> understandable, being designed primarily to support peer-to-peer
> communication between browsers, WebRTC needs STUN, ICE and TURN support for
> NAT traversal and packet forwarding in the worst case.

You don't need WebRTC's level of complexity to do P2P. WebRTC is an over-
engineered Rube Goldberg machine for many reasons, including the fact that it
tries to include so many capabilities in a single standard. It's also complex
because STUN, TURN, and ICE are overly complex. WebRTC should have used a
simpler underlying design. You really, really don't need all that. I say this
as a developer of multiple P2P protocols including some that are used in
serious applications.

Then there's stuff like: [https://github.com/js-platform/node-
webrtc](https://github.com/js-platform/node-webrtc) \-- you don't have to do
your whole backend in Node if you don't want, but you could plug something
like this in _on your servers_ and speak WebRTC to clients. In P2P a server is
just another node and there is nothing the says servers can't talk in P2P
networks.

I do believe it would be nice to have UDP in browsers somehow. In fact I think
it would have been far better to just add UDP to the browser spec and leave
WebRTC out completely. It could have been implemented in JS (and WASM in the
future) using TCP and UDP transport provided by the browser. Doing it the way
it's been done is like including application software in a computer's ROM.
It's the wrong place to put that level of abstraction.

------
captainmuon
I believe the security model in browsers is fundamentally wrong. I understand
why it evolved the way it did, but it is far from optimal.

In particular, I mean that subrequests are sent by default _with credentials_
(cookies). This is backwards. In an ideal world, I should be able to send
arbitrary anonymous HTTP requests, and should have to jump through hoops to
send along the user's cookies. In reality, it is the other way around. This is
the original sin that makes CSRF possible. Any site can send a request to any
other site I am logged into, and pretend to be me. I understand that we can't
change that now, but it just seems wrong.

Right now, you _can_ send anonymous requests (e.g. using windows.fetch), but
unless a specific CORS header is returned, you cannot access the results!
Ideally, it would be the other way around, and you could only send
authenticated requests if the target site cooperates.

Now you can make as many requests as you want (e.g. by using img or iframe
tags), but if you want to use the results, you need 1. the site's cooperation,
or 2. you need to include remote javascript. This is the next backwards thing.
Why do I have to execute remote javascript when I just want JSON data? This
should be absolutely discouraged in an ideal world!

The current security model precludes a lot of things. One is the classical
Mashup. Back then, when Web2.0 was hot, I made a simple HTML page that scraped
another website for geodata and wanted to display it on a Google Maps map.
Imagine my shock when I found that I cannot read another (open, non-
credentialed) web page with XMLHttpRequest.

There are a bunch of applications that I just cannot write within the current
security model, and I believe it is in the interest of certain people to stay
this way, so that they can remain in control of content.

The same applies even more when I think of allowing UDP or general network
access. Imagine an IMAP client or BitTorrent client in the browser. A pirate
iTunes that doesn't rely on a central server. A Tor implementation. You could
even do JS crypto somewhat securely - you wouldn't serve the .html page over
HTTP, just a simple static file that you'd deliver like any other program.

Sometimes I dream of a HTML 6+ "application profile" that would be opt-in, and
allow you to do these kind of things.

------
xg15
I think the title of the blog post is misleading.

What he really wants is a connection-oriented, TCP-like protocol with more
flexible handling of missing/delayed packets. (As this is a frequent use-case
in game development).

His solution is a UDP-based protocol that satisfies this and other use-cases
specific to networked games while keeping the connection semantics of TCP.

However the fact that it's UDP-based seems like an implementation detail to
me. The proposed solution hides a lot of other UDP-features that are not
contributing to those use-cases but would absolutely make sense in other
situations (like connectionless messages and broadcasts)

~~~
gafferongames
> What he really wants is a connection-oriented, TCP-like protocol with more
> flexible handling of missing/delayed packets. (As this is a frequent use-
> case in game development).

What I really want is the most UDP-like thing possible in the browser, that
lets people build whatever higher level protocol they want on top of it, just
like game developers do on every other platform.

Being connection based is important because if it wasn't then it would quickly
turn into a DDoS tool, or a security nightmare for probing internal networks
for vulnerabilities.

So clearly it needs to be connection based. And if it needs to be connection
based, then that rules out broadcast packets too.

~~~
irq-1
Would a clear-text token, in addition to an encrypted connect token, allow
servers to drop packets faster (since it wouldn't require decryption)? A clear
token could be changed (cached, expired) however the back-end wanted, which
would include dropping all new connection attempts when under DDOS.

I didn't see a port number anywhere. Shouldn't you define 443/UDP (or other)
as the only connection port? This would allow networks to manage the traffic,
for example dropping all UDP/443 traffic internally, or managing bandwidth at
a firewall.

Finally, shouldn't P2P be in the mix? If not now, won't we be doing this again
in a few years?

Thanks for taking on such a big challenge, and for listening to the peanut
gallery.

~~~
gafferongames
I actually do stuff like this, in the connection request packet a mix of
"additional data" protected by the AEAD as well as encrypted data (keys),
allows me to quickly reject stale tokens because the expire timestamp is
public, but protected with signature check, vs. having to fully decrypt first
to see the token is stale.

I don't have any defined port because in the game industry we tend to run
multiple game servers on the same box, so we take up a bunch of ports. I
acknowledge that this could cause issues with corporate firewalls, and would
be open to ideas how to solve this.

Regarding P2P, I think WebRTC solves the problem of browser to browser
communication just fine. Any attempt to support p2p this would just end up
rewriting WebRTC.

What I'm trying to do is solve just one small part of the problem, in a
WebSockets like way, just one thing that would enable a lot of other cool
things to be built on it, if it were adopted by browsers.

cheers

~~~
irq-1
> quickly reject stale tokens because the expire timestamp is public, but
> protected with signature check

A forged timestamp would still need a signature check, but a clear-text token
would not. The speed difference would only be important with a flood of forged
packets, each of which would need to have it's signature checked.
Additionally, each system could implement a different type of defense: like
issuing regional clear-text tokens, or A/B tokens to find which account is
leaking a clear-text token, or giving each server it's own token so a DDOS
attempt that wanted to force signature checks would need to get the right
token (and get it again when an attacked system changes it.) Hosting providers
that offer DDOS protection today could offer integrations based on clear-text
tokens that wouldn't need any interaction from a game system (other than
submitting the clear-text tokens.) I don't know if routers typically have the
ability to check a signature, but they can probably drop packets that don't
pass a (clear-text token) mask check.

The port issue is interesting. Maybe a range of ports (44300-45100) would work
for network administrators. Maybe there should be restrictions and a listing
of uses like the first 1024 (this is voice, that port's video, file transfer,
etc...)

Browsers should also limit connections. Only 2 connections/IPs at a time? Only
JavaScript from the origin domain (the address in the URL) can open
connections, not advertisements or iframes. Maybe ask the user to open
connections like browsers ask to use your location or audio/video.

I wonder too if a browser should only open a connection when presented with a
request signed using the (private) domain SSL cert? That would drastically
reduce the ability of bad JavaScript to co-opt browsers of a website (into a
DDOS of connection requests.) To use a websites traffic for a DDOS, you would
need the SSL keys. Browsers could also be required to add the domain and
verified domain sig to a connection request, so a website that cause a DDOS
would be identified. I'm not sure identifying the website would lead to
accountability since they may have been compromised, but it would prove which
domain caused a browser based DDOS; reddit.com couldn't claim a bad
advertisement caused their millions of browsers to open connections. This
wouldn't stop forged packets, but it should stop innocent web-browsers from
becoming a tool for DDOS.

------
daurnimator
> Additionally, the server enforces that only one client with a given IP
> address may be connected at any time

So much for people behind carrier NATs

~~~
gafferongames
My bad: I meant IP address + port. Fixed in the article.

~~~
hueving
Well what good is that? You can't tell if multiple IP,port pairs are from a
single client or multiple clients.

~~~
vishvananda
The nat device will have different source ports for two connected clients.

~~~
hueving
It would also have different source ports if the client is using random source
ports as well. So two client connections from the same host behind NAT would
look exactly the same as two client connections from two different hosts
behind NAT.

~~~
gafferongames
Hence the authentication on the web backend and the unique 64bit client id.

------
poop_cicle
The use of libsodium looks absolutely brilliant. Would the author recommend
using netcode.io for general games, not just agar.io or browser style stuff?

~~~
hach-que
I'm an external contributor who did the C# bindings for netcode.io available
here:
[https://github.com/RedpointGames/netcode.io](https://github.com/RedpointGames/netcode.io)

As someone who wrote her own (non-encrypted) networking protocol for desktop
games, netcode.io certainly seems easier (especially with the built-in
security), so in the near future I intend to move my projects over to using
netcode.io instead of what I have currently.

------
peterwwillis
Answer: a browser _was_ for traversing hypertext documents. UDP basically is
not good for this.

Now a browser is just an abstracted operating system. So, fuck it, I guess,
let's add a second TCP/IP stack.

~~~
geofft
The browser is a much better multi-user operating system than the actual
operating systems people tend to use. A video game on the average Windows,
Mac, or Linux desktop has full read and write access to the memory of a tax
app on the same desktop, defeating the entire point of memory protection. If
the game and the tax app are in a browser (or in a mobile OS, to their
credit), this isn't so.

That desktop OSes happen to be called "desktop OSes" and web browsers happen
to be called "web browsers" is fairly irrelevant to what they're actually good
at. Desktop OSes make great hardware abstraction layers, just as server OSes
make great hardware abstraction layers for virtualization platforms. But
they're fundamentally misdesigned for much of anything else.

~~~
AnthonyMouse
Desktop operating systems have the capacity to do this; "server operating
systems" (which are just desktop operating systems configured differently)
already do this.

You run each program as a different user account. The HTTP daemon doesn't run
as the same user as the DNS daemon even if they're on the same machine.

This is obviously _annoying_ on a desktop because you have to use user
switching to use another app. It would be better if desktop operating systems
provided native support for it so that user accounts had a sub-account per app
and apps automatically ran like that, and then a permission prompt if one app
tries to access another app's files, which you can grant as one-time access or
permanently.

Then you expect your email program to try to access a document you're
attaching to an email, but if a video game tries to read your tax returns you
can be appropriately suspicious.

~~~
geofft
Correct. This is a design problem, caused by building ill-suited interfaces.
(This isn't a criticism of the people who designed the interfaces; we simply
didn't have the depth of experience when UNIX and Win32 and their predecessors
were designed, and now we're stuck with compatibility for those.)

The interface between a web page and the outside world allows it to do things
like access its site and not others, request a particular file be opened, send
structured messages to other sites that wish to opt in to such access, etc.

The interface between a process and the outside world gives it either TCP
sockets on behalf of the machine, or nothing at all; either the ability to
open any file as the current user, or nothing at all.

I used to be excited about proposals for desktop operating systems to provide
sandboxing via multiple UIDs and native interfaces for passing files around
and powerboxes and all of that good stuff. Then I realized that the web
platform does all of that and is very widely adopted and well-tested, and
there's no hope of the existing platforms catching up.

I used to have two user accounts, one of which was allowed to run the Flash
plugin so I could listen to music, and one of which held my important work.
Then the web folks figured out how to sandbox the Flash plugin without
requiring me to Ctrl-Alt-F8 to pause a song. Then they figured out how to not
use a native-code plugin at all.

I don't particularly _like_ this conclusion in an abstract sense, but it's
certainly let me get on with getting things done instead of hoping for a
future that will never come.

------
dragonwriter
> Why can't I send UDP packets from a browser?

You can, if the browser is Chrome:
[https://developer.chrome.com/apps/sockets_udp](https://developer.chrome.com/apps/sockets_udp)

~~~
Groxx
Worth noting this is using the "chrome.etc" object, which is only available to
apps and/or extensions.

~~~
duskwuff
Which, at this point, just means extensions:
[https://blog.chromium.org/2016/08/from-chrome-apps-to-
web.ht...](https://blog.chromium.org/2016/08/from-chrome-apps-to-web.html)

~~~
Groxx
There are still critical holes in the extension API that they haven't plugged,
e.g. filesystem access (super duper important if you want to make an app that
can edit / create images, for instance, and not want to shove everything into
the downloads folder or force a chooser every time). I'm not sure how they're
going to shut things down while crippling the ecosystem so severely (though to
be fair, Firefox is doing a similar crippling-move (but for solid reasons,
IMO)).

------
VengefulCynic
Obviously going out of his way to implement in a secure way as a software
practitioner. I would love to see a review of the design and implementation
from the standpoint of a security expert.

------
daurnimator
Interesting idea I had: why not have _many_ QUIC streams?

~~~
areed
Are you thinking one stream per packet?

~~~
endianswap
You could have a pool of them, right? Or would you have to actually tear it
down after each packet

------
ungzd
Minecraft works great over TCP[1], so casual clickers like agar.io mentioned
there, and most games except fast-paced shooters will work too.

[1] [http://wiki.vg/Protocol](http://wiki.vg/Protocol)

~~~
amaranth
Minecraft "works" over TCP but I wouldn't call it great. TCP works great for
things like block data since keeping those ordered makes it easy to send
changes instead of resending whole chunks. On the other hand, entity movement
being TCP is a real pain due to the head of line blocking which is one of the
reasons PvP can be a pain and why it can be impossible to melee mobs without
them hitting you first.

------
nvarsj
Some things I noticed about the proposed protocol:

\- It's not clear how data is encrypted. I don't see a client key being
generated. It will be very difficult to do this right without using something
like TLS. Are the keys just sent over an unencrypted channel?

\- The connect token should contain the client's IP address, so the server can
verify the same IP that got the token is trying to connect. This prevents
someone from using a valid token for reflection attacks.

~~~
IshKebab
Presumably the keys are sent over HTTPS.

~~~
gafferongames
Yes, the connect token is transmitted from web backend to client over HTTPS.

This token contains public and private data. The public data tells the client
which servers to connect to, what the keys are etc, hence the need for HTTPS.

The private data is what gets sent over UDP in connection handshake, and is
encrypted with a libsodium AEAD primitive using a private key shared between
the backend matchmaker and the dedicated server instances.

Because of this clients cannot read, modify or forge the connect token private
data, so cannot connect unless they get a token from the backend.

Tokens are only valid for a specific authenticated client to connect to a
small set of n dedicated servers, and expire quickly (30-45 seconds).

------
dolftax
Do the authentication over TCP and then fallback to UDP for rest of the
communication? For encryption, have you considered DTLS? Read more in `Hybrid
Implementation` section of [http://ithare.com/udp-for-games-security-
encryption-and-ddos...](http://ithare.com/udp-for-games-security-encryption-
and-ddos-protection/)

------
CrLf
The article misses one important reason why allowing UDP from the browser is a
bad idea:

UDP provides no congestion control. Given the (lack of) quality of what gets
developed for the browser, allowing it to send raw UDP would most likely cause
an extraordinary amount of problems for the Internet as a whole.

~~~
gafferongames
Games have been spamming UDP packets over the Internet for the last 20 years
and the Internet seems to be doing OK.

------
Kiro
Why enforce server limits? I'm building a multiplayer game where user actions
can happen at most every 150 ms. Am I naive thinking that one server should be
able to handle thousands of simultaneous users? I understand the limits when
it comes to fast-paced games though.

~~~
Cthulhu_
It depends. MMO's can generally handle thousands of users per second, but
realistically those generate only one event per second. There's faster-paced
games like Planetside and Battlefield which allow for hundreds of users per
server though.

~~~
Kiro
Thanks!

> but realistically those generate only one event per second

How does that work with seeing other avatars walking around in real-time in
for example WoW? Are their trajectory only updated once a second? In my game
it's not really displayed in that way but I'm curious.

~~~
shultays
Player position is not very critical in WoW or similar games. Combat is mostly
selecting an enemy and attacking it. Or selecting enemy and casting a ranged
spell. The game is designed with this server lag in the mind.

Servers can easily sync player positions once per second and the clients would
happily interpolate between prev & current positions. You are probably seeing
things a little late/different than server but it does not matter.

------
mido22
can't understand this bashing of WebRTC, it is good technology, TURN config is
optional is not compulsory, but believe STUN is still necessary because,
unlike the public server, the client is behind NAT, but then again, setting up
a TURN+STUN server is a trivial job...

~~~
ambrop7
Why would STUN be necessary if the client is behind NAT? So long as the server
is not, the client can send the first packet and NATs will establish
associations for the packets from the server to arrive to the client.

------
gnu8
Why can't I DDoS an arbitrary host using nothing but twitter accounts?

------
benaadams
Also includes alternative protocol implementation design and source for
protocol.

Would love a simple way to do client<->server udp from browser!

------
signa11
on mobile devices or accessing internet through mobile network, i would wager
that it is congestion control which causes more heartburn than head-of-line-
blocking.

this is predicated on the fact that packet loss e.g. due to poor signal etc.
is conflated with congestion in the network. this then results in tcp
reverting to slow-start etc etc

------
iamleppert
You could always use something like Electron if you can get users to download
your app, which would allow you to use whatever node native networking
libraries there are, I'm sure you could send UDP packets or anything else, and
still use web technologies and the browser to develop your app/game.

~~~
iamleppert
Why was this down voted? lol its a legitimate solution..

------
shurcooL
> Why can't I send UDP packets from a browser?

My tweet from May 2015 is titled "I've sent my first UDP packet from a
browser!" [1]

[1]
[https://twitter.com/shurcooL/status/605218976969261056](https://twitter.com/shurcooL/status/605218976969261056)

~~~
djsumdog
Looks like Firefox? Did you write a browser extension?

~~~
philo23
It's from Firefox OS: [https://developer.mozilla.org/en-
US/docs/Mozilla/B2G_OS/API/...](https://developer.mozilla.org/en-
US/docs/Mozilla/B2G_OS/API/UDPSocket)

~~~
shurcooL
No, it was an experimental implementation of [https://www.w3.org/TR/tcp-udp-
sockets/](https://www.w3.org/TR/tcp-udp-sockets/) actually. Regular Firefox
browser, not Firefox OS.

------
greggman
I'm not really sympathetic to the arguments against WebRTC. Ideally someone
makes an open source library or 12, problem solved.

In fact looking at other comments here it sounds like it's not hard at all.

One other problem with WebRTC at the moment though, it's not supported by
Safari

~~~
daveorzach
WebRTC will be enabled in Safari production builds shortly
[https://bugs.webkit.org/show_bug.cgi?id=168858](https://bugs.webkit.org/show_bug.cgi?id=168858)

------
machty
Could the "connect" token just be a JWT token?

------
Rapzid
Network congestion.

------
vans
Cool, another protocol which claims for security and a reference
implementation in... C

------
bandrami
Because there's no such thing as UDP "packets"?

------
josteink
So let me get this straight... Basically this guy is trying to champion one of
two things:

\- Yet another attempt to emulate a full OS-level network stack on top of HTTP
(which already runs on top of TCP/IP).

\- Giving random web-pages access to RAW OS-level networking, and not just
sockets, from untrusted internet JS.

How incredibly ass backwards am I if I find both proposals preposterous and
dangerous?

> One solution would be for Google to make it significantly easier for game
> developers to integrate WebRTC data channel support in their dedicated
> servers.

I'm confused. Since when did Google decide what was web-standards? Is he
deliberately mistaking Google for being W3C?

~~~
scribu
I don't think you got it straight.

> Yet another attempt to emulate a full OS-level network stack on top of HTTP

The proposed protocol does not work "on top of" HTTP. From the article:

> The basic idea is that the web backend performs authentication and when a
> client wants to play, it makes a REST call to obtain a connect token which
> is passed to the dedicated server as part of the connection handshake over
> UDP.

So both the handshake and the actual data transfer happen directly over UDP.

Next:

> Giving random web-pages access to RAW OS-level networking, and not just
> sockets, from untrusted internet JS.

The "Why not just let people send UDP?" section in the article actually
explains why that would _not_ be a good idea.

------
mostafaberg
I kinda disagree with the premise about UDP:

> It would greatly improve the networking of these games.

This is not accurate, i know it's like a rule of thumb that UDP is faster than
TCP, but that's naive, there are cases where UDP will end up being slower, and
to be honest, it depends on lots of variables, and at many times, the
congestion control, packet ordering and all the bells and whistles that comes
with TCP is well worth the little performance penalty, assuming that in that
specific case it actually is slower than UDP

And of course if I'm wrong, someone will let me know :D

~~~
pja
What people usually want is all the bells and whistles of TCP without the
occasional huge latency spike introduced by the guaranteed ordered packet
delivery to the application layer.

Unfortunately, all the alternatives (SCTP etc etc) seem to have foundered,
probably due to aggressive filtering by border routers/firewalls making it
impossible for alternative protocols to gain traction.

~~~
mostafaberg
Exactly my point about the whole "many variables involved", many networks
still filter UDP as you say, which is really bad if you want to make sure
everyone can use your game

