aboutsummaryrefslogtreecommitdiff
path: root/src/util/sock.h
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2020-12-04 15:11:25 +0100
committerVasil Dimov <vd@FreeBSD.org>2021-03-01 17:36:16 +0100
commit42c779f503eb8437b6232773a4a2472306cc9f3d (patch)
treeb8e4af2a0a315f717f13589b8f66db3926ac56e9 /src/util/sock.h
parentea1845315a109eb105113cb5fbb6f869e1cf010c (diff)
net: extend Sock with methods for robust send & read until terminator
Introduce two high level, convenience methods in the `Sock` class: * `SendComplete()`: keep trying to send the specified data until either successfully sent all of it, timeout or interrupted. * `RecvUntilTerminator()`: read until a terminator is encountered (never after it), timeout or interrupted. These will be convenient in the I2P SAM implementation. `SendComplete()` can also be used in the SOCKS5 implementation instead of calling `send()` directly.
Diffstat (limited to 'src/util/sock.h')
-rw-r--r--src/util/sock.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/util/sock.h b/src/util/sock.h
index 2d9cac14af..209d30def4 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -6,6 +6,7 @@
#define BITCOIN_UTIL_SOCK_H
#include <compat.h>
+#include <threadinterrupt.h>
#include <util/time.h>
#include <chrono>
@@ -114,6 +115,34 @@ public:
Event requested,
Event* occurred = nullptr) const;
+ /* Higher level, convenience, methods. These may throw. */
+
+ /**
+ * Send the given data, retrying on transient errors.
+ * @param[in] data Data to send.
+ * @param[in] timeout Timeout for the entire operation.
+ * @param[in] interrupt If this is signaled then the operation is canceled.
+ * @throws std::runtime_error if the operation cannot be completed. In this case only some of
+ * the data will be written to the socket.
+ */
+ virtual void SendComplete(const std::string& data,
+ std::chrono::milliseconds timeout,
+ CThreadInterrupt& interrupt) const;
+
+ /**
+ * Read from socket until a terminator character is encountered. Will never consume bytes past
+ * the terminator from the socket.
+ * @param[in] terminator Character up to which to read from the socket.
+ * @param[in] timeout Timeout for the entire operation.
+ * @param[in] interrupt If this is signaled then the operation is canceled.
+ * @return The data that has been read, without the terminating character.
+ * @throws std::runtime_error if the operation cannot be completed. In this case some bytes may
+ * have been consumed from the socket.
+ */
+ virtual std::string RecvUntilTerminator(uint8_t terminator,
+ std::chrono::milliseconds timeout,
+ CThreadInterrupt& interrupt) const;
+
private:
/**
* Contained socket. `INVALID_SOCKET` designates the object is empty.