Skip to content

Commit

Permalink
Verify TCP Connections are open before allowing data to be written. (#…
Browse files Browse the repository at this point in the history
…1341)

Prevent subtle bugs and potential runaway memory usage that can be introduced by being unfamiliar with the internals of the `TCPConnection` class.

As a result of this change when writing to the connection data will be silently discarded if the connection has not yet been established.

Resolves: #1310
See also: https://github.com/ponylang/rfcs/blob/master/text/0016-tcp-must-be-connected.md
  • Loading branch information
drannise authored and SeanTAllen committed Jan 10, 2017
1 parent b0ec1db commit 74555f7
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ All notable changes to the Pony compiler and standard library will be documented

### Changed

- Ensure TCPConnection is established before writing data to it (issue #1310)
- Deprecate LLVM 3.6 OSX support (PR #1502)
- Always allow writing to `_` (dontcare) (PR #1499)
- Methods returning their receiver to allow call chaining have been changed to return either None or some useful value. Generalised method chaining implemented in version 0.9.0 should be used as a replacement. The full list of updated methods follows. No details means that the method now returns None.
Expand Down
20 changes: 13 additions & 7 deletions packages/net/tcp_connection.pony
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ actor TCPConnection
end
```
Note: when writing to the connection data will be silently discarded if the
connection has not yet been established.
## Backpressure support
### Write
Expand Down Expand Up @@ -247,19 +250,21 @@ actor TCPConnection

be write(data: ByteSeq) =>
"""
Write a single sequence of bytes.
Write a single sequence of bytes. Data will be silently discarded if the
connection has not yet been established though.
"""
if not _closed then
if _connected and not _closed then
_in_sent = true
write_final(_notify.sent(this, data))
_in_sent = false
end

be writev(data: ByteSeqIter) =>
"""
Write a sequence of sequences of bytes.
Write a sequence of sequences of bytes. Data will be silently discarded if
the connection has not yet been established though.
"""
if not _closed then
if _connected and not _closed then
_in_sent = true

for bytes in _notify.sentv(this, data).values() do
Expand Down Expand Up @@ -416,10 +421,11 @@ actor TCPConnection
fun ref write_final(data: ByteSeq) =>
"""
Write as much as possible to the socket. Set `_writeable` to `false` if not
everything was written. On an error, close the connection. This is for
data that has already been transformed by the notifier.
everything was written. On an error, close the connection. This is for data
that has already been transformed by the notifier. Data will be silently
discarded if the connection has not yet been established though.
"""
if not _closed then
if _connected and not _closed then
ifdef windows then
try
// Add an IOCP write.
Expand Down

0 comments on commit 74555f7

Please sign in to comment.