From 74555f737242bd3b0824bc72d1e3ca23bdbc3619 Mon Sep 17 00:00:00 2001 From: Sergey Drannikov Date: Tue, 10 Jan 2017 12:21:42 +0000 Subject: [PATCH] Verify TCP Connections are open before allowing data to be written. (#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 --- CHANGELOG.md | 1 + packages/net/tcp_connection.pony | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa57169e3b..631d3db66d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/packages/net/tcp_connection.pony b/packages/net/tcp_connection.pony index 61f9dacb28..2b3bb6653d 100644 --- a/packages/net/tcp_connection.pony +++ b/packages/net/tcp_connection.pony @@ -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 @@ -247,9 +250,10 @@ 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 @@ -257,9 +261,10 @@ actor TCPConnection 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 @@ -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.