Using empty struct for signaling is more idiomatic
compared to booleans because users might wonder
what happens on false or true. Empty struct removes
this problem.
There is also a side benefit of occupying less memory
but it should be negligible in this case.
This fix addresses a potential denial-of-service (DoS) vector that can cause an integer overflow in the presence of malicious WebSocket frames.
The fix adds additional checks against the remaining bytes on a connection, as well as a test to prevent regression.
Credit to Max Justicz (https://justi.cz/) for discovering and reporting this, as well as providing a robust PoC and review.
* build: go.mod to go1.12
* bugfix: fix DoS vector caused by readLimit bypass
* test: update TestReadLimit sub-test
* bugfix: payload length 127 should read bytes as uint64
* bugfix: defend against readLength overflows
Fix bug where connection did not return the write buffer to the pool
after a write error. Add test for the same.
Rename messsageWriter.fatal method to endMessage and consolidate all
message cleanup code there. This ensures that the buffer is returned to
pool on all code paths.
Rename Conn.prepMessage to beginMessage for symmetry with endMessage.
Move some duplicated code at calls to prepMessage to beginMessage.
Bonus improvement: Adjust message and buffer size in TestWriteBufferPool
to test that pool works with fragmented messages.
Add WriteBufferPool to Dialer and Upgrader. This field specifies a pool
to use for write operations on a connection. Use of the pool can reduce
memory use when there is a modest write volume over a large number of
connections.
Use larger of hijacked buffer and buffer allocated for connection (if
any) as buffer for building handshake response. This decreases possible
allocations when building the handshake response.
Modify bufio reuse test to call Upgrade instead of the internal
newConnBRW. Move the test from conn_test.go to server_test.go because
it's a serer test.
Update newConn and newConnBRW:
- Move the bufio "hacks" from newConnBRW to separate functions and call
these functions directly from Upgrade.
- Rename newConn to newTestConn and move to conn_test.go. Shorten
argument list to common use case.
- Rename newConnBRW to newConn.
- Add pool code to newConn.
The documentation sometimes used the term "frame" when referring to
single frame control messages. Use the term "message" for consistency
in the documentation and to hide a detail that most application
programmers do not need to know about.
Return empty message for CloseNoStatusReceived. This status indicates
that the message is empty, so make it so. Because it's illegal to send
CloseNoStatusReceived, this change should not break a correct
application.
Reuse the buffer backing the bufio.Writer returned from hijack if that
buffer is large enough to be generally useful and
Upgrader.WriteBufferSize == 0.
Update the logic for reusing bufio.Reader returned from hijack to match
the logic for bufio.Reader: The buffer backing the reader must be
sufficiently large to be generally useful and Upgrader.ReadBufferSize ==
0.
Improve the documentation for ReadBufferSize and WriterBufferSize in
Dialer and Upgrader.