aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2021-01-21 16:59:55 +0100
committerVasil Dimov <vd@FreeBSD.org>2021-03-01 17:36:17 +0100
commit5bac7e45e1d3a07115b5ff002d988438fcc92a53 (patch)
tree585c003f2f4a826dd8037cb85509486053b84c78 /src
parent42c779f503eb8437b6232773a4a2472306cc9f3d (diff)
downloadbitcoin-5bac7e45e1d3a07115b5ff002d988438fcc92a53.tar.xz
net: extend Sock with a method to check whether connected
This will be convenient in the I2P SAM implementation.
Diffstat (limited to 'src')
-rw-r--r--src/util/sock.cpp25
-rw-r--r--src/util/sock.h7
2 files changed, 32 insertions, 0 deletions
diff --git a/src/util/sock.cpp b/src/util/sock.cpp
index 36493ec241..e13c52a16a 100644
--- a/src/util/sock.cpp
+++ b/src/util/sock.cpp
@@ -250,6 +250,31 @@ std::string Sock::RecvUntilTerminator(uint8_t terminator,
}
}
+bool Sock::IsConnected(std::string& errmsg) const
+{
+ if (m_socket == INVALID_SOCKET) {
+ errmsg = "not connected";
+ return false;
+ }
+
+ char c;
+ switch (Recv(&c, sizeof(c), MSG_PEEK)) {
+ case -1: {
+ const int err = WSAGetLastError();
+ if (IOErrorIsPermanent(err)) {
+ errmsg = NetworkErrorString(err);
+ return false;
+ }
+ return true;
+ }
+ case 0:
+ errmsg = "closed";
+ return false;
+ default:
+ return true;
+ }
+}
+
#ifdef WIN32
std::string NetworkErrorString(int err)
{
diff --git a/src/util/sock.h b/src/util/sock.h
index 209d30def4..ecebb84205 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -143,6 +143,13 @@ public:
std::chrono::milliseconds timeout,
CThreadInterrupt& interrupt) const;
+ /**
+ * Check if still connected.
+ * @param[out] err The error string, if the socket has been disconnected.
+ * @return true if connected
+ */
+ virtual bool IsConnected(std::string& errmsg) const;
+
private:
/**
* Contained socket. `INVALID_SOCKET` designates the object is empty.