upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/sockcount.h
diff options
context:
space:
mode:
authorBitflash <btf01@proton.me>2026-08-01 18:43:25 -0300
committerGitHub <noreply@github.com>2026-08-01 18:43:25 -0300
commit2ffc50998c30f285f45c5c5d81975bf857885aa8 (patch)
tree9fe6be3a0dd7a8f869c88f9c1dd13e75fa8e7b78 /src/sockcount.h
parent19ecd6ad61b560d92d82ed5a79b5217d64f97327 (diff)
diag: say why a close failed, and total what the program thinks it holds (#98)
The 1.2.11 accounting answered 'which site' and stopped. On a node with 3h51m of uptime it reported 58 live sockets while Windows attributed 112 to the process, 47 of them bound and never connected, against 55 closes that had returned an error -- with nothing recording what those errors were. Close failures are now counted per code per site, and the table totals, so the live figure can be compared directly against what the OS attributes to the process. Instrumentation only.
Diffstat (limited to 'src/sockcount.h')
-rw-r--r--src/sockcount.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/sockcount.h b/src/sockcount.h
index 19f0827..a42abb9 100644
--- a/src/sockcount.h
+++ b/src/sockcount.h
@@ -23,6 +23,7 @@
23#ifndef BITFLASH_SOCKCOUNT_H 23#ifndef BITFLASH_SOCKCOUNT_H
24#define BITFLASH_SOCKCOUNT_H 24#define BITFLASH_SOCKCOUNT_H
25 25
26#include <cerrno>
26#include <map> 27#include <map>
27#include <mutex> 28#include <mutex>
28 29
@@ -52,6 +53,13 @@ struct BtfSockAccount
52 long long nOpened[SOCK_SITES]; 53 long long nOpened[SOCK_SITES];
53 long long nClosed[SOCK_SITES]; 54 long long nClosed[SOCK_SITES];
54 long long nCloseFailed[SOCK_SITES]; 55 long long nCloseFailed[SOCK_SITES];
56 // Why the close failed, counted per code per site. Measured on a node with
57 // 3h51m of uptime: the program believed it held 58 sockets and Windows
58 // attributed 112 to the process, 47 of them bound to an ephemeral port and
59 // never connected -- against 55 closes that had returned an error. The
60 // shapes match, and the error code is the piece that says whether the
61 // descriptor is still there or was already gone.
62 std::map<int, long long> mapCloseErr[SOCK_SITES];
55 long long nClosedUntagged; 63 long long nClosedUntagged;
56 BtfSockAccount() : nClosedUntagged(0) 64 BtfSockAccount() : nClosedUntagged(0)
57 { 65 {
@@ -102,8 +110,10 @@ inline int BtfCloseSocket(SOCKET hSocket)
102 } 110 }
103#ifdef _WIN32 111#ifdef _WIN32
104 int nRet = ::closesocket(hSocket); 112 int nRet = ::closesocket(hSocket);
113 int nErr = (nRet != 0) ? WSAGetLastError() : 0;
105#else 114#else
106 int nRet = ::close(hSocket); 115 int nRet = ::close(hSocket);
116 int nErr = (nRet != 0) ? errno : 0;
107#endif 117#endif
108 // A close that fails leaves the descriptor -- and on Windows the ephemeral 118 // A close that fails leaves the descriptor -- and on Windows the ephemeral
109 // port it holds -- in place. Counted because a socket the program believes 119 // port it holds -- in place. Counted because a socket the program believes
@@ -115,6 +125,7 @@ inline int BtfCloseSocket(SOCKET hSocket)
115 BtfSockAccount& a = BtfSockAccounting(); 125 BtfSockAccount& a = BtfSockAccounting();
116 std::lock_guard<std::mutex> lock(a.mtx); 126 std::lock_guard<std::mutex> lock(a.mtx);
117 a.nCloseFailed[nSite]++; 127 a.nCloseFailed[nSite]++;
128 a.mapCloseErr[nSite][nErr]++;
118 } 129 }
119 return nRet; 130 return nRet;
120} 131}
@@ -134,4 +145,16 @@ inline void BtfSockSnapshot(long long* pOpened, long long* pClosed, long long* p
134 *pUntagged = a.nClosedUntagged; 145 *pUntagged = a.nClosedUntagged;
135} 146}
136 147
148// The close-failure codes for one site, newest counts included. Separate call
149// because the table above is fixed-width and this is a list of unknown length.
150inline void BtfSockCloseErrors(int nSite, std::map<int, long long>& mapOut)
151{
152 mapOut.clear();
153 if (nSite < 0 || nSite >= SOCK_SITES)
154 return;
155 BtfSockAccount& a = BtfSockAccounting();
156 std::lock_guard<std::mutex> lock(a.mtx);
157 mapOut = a.mapCloseErr[nSite];
158}
159
137#endif 160#endif