aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
AgeCommit message (Collapse)Author
2023-11-07Merge bitcoin/bitcoin#28649: Do the SOCKS5 handshake reliablyAndrew Chow
af0fca530e4d8311bcb24a14c416e5ad7c30ff78 netbase: use reliable send() during SOCKS5 handshake (Vasil Dimov) 1b19d1117ca5373a15313227b547ef4392022dbd sock: change Sock::SendComplete() to take Span (Vasil Dimov) Pull request description: The `Socks5()` function which does the SOCKS5 handshake with the SOCKS5 proxy sends bytes to the socket without retrying partial writes. `send(2)` may write only part of the provided data and return. In this case the caller is responsible for retrying the operation with the remaining data. Change `Socks5()` to do that. There is already a method `Sock::SendComplete()` which does exactly that, so use it in `Socks5()`. A minor complication for this PR is that `Sock::SendComplete()` takes `std::string` argument whereas `Socks5()` has `std::vector<uint8_t>`. Thus the necessity for the first commit. It is possible to do also in other ways - convert the data in `Socks5()` to `std::string` or have just one `Sock::SendComplete()` that takes `void*` and change the callers to pass `str.data(), str.size()` or `vec.data(), vec.size()`. This came up while testing https://github.com/bitcoin/bitcoin/pull/27375. ACKs for top commit: achow101: ACK af0fca530e4d8311bcb24a14c416e5ad7c30ff78 jonatack: ACK af0fca530e4d8311bcb24a14c416e5ad7c30ff78 pinheadmz: ACK af0fca530e4d8311bcb24a14c416e5ad7c30ff78 Tree-SHA512: 1d4a53d0628f7607378038ac56dc3b8624ce9322b034c9547a0c3ce052eafb4b18213f258aa3b57bcb4d990a5e0548a37ec70af2bd55f6e8e6399936f1ce047a
2023-10-31netbase: use reliable send() during SOCKS5 handshakeVasil Dimov
`send(2)` can be interrupted or for another reason it may not fully complete sending all the bytes. We should be ready to retry the send with the remaining bytes. This is what `Sock::SendComplete()` does, thus use it in `Socks5()`. Since `Sock::SendComplete()` takes a `CThreadInterrupt` argument, change also the recv part of `Socks5()` to use `CThreadInterrupt` instead of a boolean. Easier reviewed with `git show -b` (ignore white-space changes).
2023-10-30net/rpc: Makes CConnman::GetAddedNodeInfo able to return only non-connected ↵Sergi Delgado Segura
address on request `CConnman::GetAddedNodeInfo` is used both to get a list of addresses to manually connect to in `CConnman::ThreadOpenAddedConnections`, and to report about manually added connections in `getaddednodeinfo`. In both cases, all addresses added to `m_added_nodes` are returned, however the nodes we are already connected to are only relevant to the latter, in the former they are actively discarded. Parametrizes `CConnman::GetAddedNodeInfo` so we can ask for only addresses we are not connected to, to avoid passing useless information around.
2023-10-30rpc: Prevents adding the same ip more than once when formatted differentlySergi Delgado Segura
Currently it is possible to add the same node twice when formatting IPs in different, yet equivalent, manner. This applies to both ipv4 and ipv6, e.g: 127.0.0.1 = 127.1 | [::1] = [0:0:0:0:0:0:0:1] `addnode` will accept both and display both as connected (given they translate to the same IP). This will not result in multiple connections to the same node, but will report redundant info when querying `getaddednodeinfo` and populate `m_added_nodes` with redundant data. This can be avoided performing comparing the contents of `m_added_addr` and the address to be added as `CServices` instead of as strings.
2023-10-30net/rpc: Check all resolved addresses in ConnectNode rather than just oneSergi Delgado Segura
The current `addnode` rpc command has some edge cases in where it is possible to connect to the same node twice by combining ip and address requests. This can happen under two situations: The two commands are run one right after each other, in which case they will be processed under the same loop in `CConnman::ThreadOpenAddedConnections` without refreshing `vInfo`, so both will go trough. An example of this would be: ``` bitcoin-cli addnode "localhost:port" add ``` A node is added by IP using `addnode "add"` while the other is added by name using `addnode "onetry"` with an address that resolves to multiple IPs. In this case, we currently only check one of the resolved IPs (picked at random), instead of all the resolved ones, meaning this will only probabilistically fail/succeed. An example of this would be: ``` bitcoin-cli addnode "127.0.0.1:port" add [...] bitcoin-cli addnode "localhost:port" onetry ``` Both cases can be fixed by iterating over all resolved addresses in `CConnman::ConnectNode` instead of picking one at random
2023-10-24build: Bump minimum supported Clang to clang-13MarcoFalke
2023-10-19Merge bitcoin/bitcoin#28077: I2P: also sleep after errors in Accept() & ↵Andrew Chow
destroy the session if we get an unexpected error 5c8e15c451ec870b9dd4eb843ec6ca3ba64cda4f i2p: destroy the session if we get an unexpected error from the I2P router (Vasil Dimov) 762404a68c114e8831cdfae937627174544b55a7 i2p: also sleep after errors in Accept() (Vasil Dimov) Pull request description: ### Background In the `i2p::sam::Session` class: `Listen()` does: * if the session is not created yet * create the control socket and on it: * `HELLO` * `SESSION CREATE ID=sessid` * leave the control socked opened * create a new socket and on it: * `HELLO` * `STREAM ACCEPT ID=sessid` * read reply (`STREAM STATUS`), `Listen()` only succeeds if it contains `RESULT=OK` Then a wait starts, for a peer to connect. When connected, `Accept()` does: * on the socket from `STREAM ACCEPT` from `Listen()`: read the Base64 identification of the connecting peer ### Problem The I2P router may be in such a state that this happens in a quick succession (many times per second, see https://github.com/bitcoin/bitcoin/issues/22759#issuecomment-1609907115): `Listen()`-succeeds, `Accept()`-fails. `Accept()` fails because the I2P router sends something that is not Base64 on the socket: `STREAM STATUS RESULT=I2P_ERROR MESSAGE="Session was closed"` We only sleep after failed `Listen()` because the assumption was that if `Accept()` fails then the next `Listen()` will also fail. ### Solution Avoid filling the log with "Error accepting:" messages and sleep also after a failed `Accept()`. ### Extra changes * Reset the error waiting time after one successful connection. Otherwise the timer will remain high due to problems that have been solved long time in the past. * Increment the wait time less aggressively. * Handle the unexpected "Session was closed" message more gracefully (don't log stupid messages like `Cannot decode Base64: "STREAM STATUS...`) and destroy the session right way. ACKs for top commit: achow101: ACK 5c8e15c451ec870b9dd4eb843ec6ca3ba64cda4f jonatack: re-ACK 5c8e15c451ec870b9dd4eb843ec6ca3ba64cda4f Tree-SHA512: 1d47958c50eeae9eefcb668b8539fd092adead93328e4bf3355267819304b99ab41cbe1b5dbedbc3452c2bc389dc8330c0e27eb5ccb880e33dc46930a1592885
2023-10-16net: remove unused CConnman::FindNode(const CSubNet&)Vasil Dimov
2023-10-05net: move MaybeFlipIPv6toCJDNS() from net to netbaseVasil Dimov
It need not be in the `net` module and we need to call it from `LookupSubNet()`, thus move it to `netbase`.
2023-10-05net: move IsReachable() code to netbase and encapsulate itVasil Dimov
`vfLimited`, `IsReachable()`, `SetReachable()` need not be in the `net` module. Move them to `netbase` because they will be needed in `LookupSubNet()` to possibly flip the result to CJDNS (if that network is reachable). In the process, encapsulate them in a class. `NET_UNROUTABLE` and `NET_INTERNAL` are no longer ignored when adding or removing reachable networks. This was unnecessary.
2023-10-05i2p: also sleep after errors in Accept()Vasil Dimov
Background: `Listen()` does: * if the session is not created yet * create the control socket and on it: * `HELLO` * `SESSION CREATE ID=sessid` * leave the control socked opened * create a new socket and on it: * `HELLO` * `STREAM ACCEPT ID=sessid` * read reply (`STREAM STATUS`) Then a wait starts, for a peer to connect. When connected, `Accept()` does: * on the socket from `STREAM ACCEPT` from `Listen()`: read the Base64 identification of the connecting peer Problem: The I2P router may be in such a state that this happens in a quick succession (many times per second, see https://github.com/bitcoin/bitcoin/issues/22759#issuecomment-1609907115): `Listen()`-succeeds, `Accept()`-fails. `Accept()` fails because the I2P router sends something that is not Base64 on the socket: STREAM STATUS RESULT=I2P_ERROR MESSAGE="Session was closed" We only sleep after failed `Listen()` because the assumption was that if `Accept()` fails then the next `Listen()` will also fail. Solution: Avoid filling the log with "Error accepting:" messages and sleep also after a failed `Accept()`. Extra changes: * Reset the error waiting time after one successful connection. Otherwise the timer will remain high due to problems that have vanished long time ago. * Increment the wait time less aggressively.
2023-10-04net: Optionally include terrible addresses in GetAddr resultsFabian Jahr
2023-10-04net: raise V1_PREFIX_LEN from 12 to 16Pieter Wuille
A "version" message in the V1 protocol starts with a fixed 16 bytes: * The 4-byte network magic * The 12-byte zero-padded command "version" plus 5 0x00 bytes The current code detects incoming V1 connections by just looking at the first 12 bytes (matching an earlier version of BIP324), but 16 bytes is more precise. This isn't an observable difference right now, as a 12 byte prefix ought to be negligible already, but it may become observable with future extensions to the protocol, so make the code match the specification.
2023-10-03scripted-diff: Rename connection limit variablesAmiti Uttarwar
-BEGIN VERIFY SCRIPT- sed -i 's/nMaxConnections/m_max_automatic_connections/g' src/net.h src/net.cpp sed -i 's/\.nMaxConnections/\.m_max_automatic_connections/g' src/init.cpp src/test/denialofservice_tests.cpp sed -i 's/nMaxFeeler/m_max_feeler/g' src/net.h sed -i 's/nMaxAddnode/m_max_addnode/g' src/net.h src/net.cpp sed -i 's/m_max_outbound\([^_]\)/m_max_automatic_outbound\1/g' src/net.h src/net.cpp -END VERIFY SCRIPT- Co-authored-by: Martin Zumsande <mzumsande@gmail.com>
2023-10-03net: add m_max_inbound to connmanAmiti Uttarwar
Extract the logic for calculating & maintaining inbound connection limits to be a member within connman for consistency with other maximum connection limits. Note that we now limit m_max_inbound to 0 and don't call AttemptToEvictConnection() when we don't have any inbounds. Previously, nMaxInbound could become negative if the user ran with a low -maxconnections, which didn't break any logic but didn't make sense. Co-authored-by: Martin Zumsande <mzumsande@gmail.com>
2023-10-03Merge bitcoin/bitcoin#26312: Remove Sock::Get() and Sock::Sock()Ryan Ofsky
7df450836969b81e98322c9a09c08b35d1095a25 test: improve sock_tests/move_assignment (Vasil Dimov) 5086a99b84367a45706af7197da1016dd966e6d9 net: remove Sock default constructor, it's not necessary (Vasil Dimov) 7829272f7826511241defd34954e6040ea963f07 net: remove now unnecessary Sock::Get() (Vasil Dimov) 944b21b70ae490a5a746bcc1810a5074d74e9d34 net: don't check if the socket is valid in ConnectSocketDirectly() (Vasil Dimov) aeac68d036e3cff57ce155f1a904d77f98b357d4 net: don't check if the socket is valid in GetBindAddress() (Vasil Dimov) 5ac1a51ee5a57da59f1ff1986b7d9054484d3c80 i2p: avoid using Sock::Get() for checking for a valid socket (Vasil Dimov) Pull request description: _This is a piece of #21878, chopped off to ease review._ Peeking at the underlying socket file descriptor of `Sock` and checkig if it is `INVALID_SOCKET` is bad encapsulation and stands in the way of testing/mocking/fuzzing. Instead use an empty `unique_ptr` to denote that there is no valid socket where appropriate or outright remove such checks where they are not necessary. The default constructor `Sock::Sock()` is unnecessary now after recent changes, thus remove it. ACKs for top commit: ajtowns: ACK 7df450836969b81e98322c9a09c08b35d1095a25 jonatack: ACK 7df450836969b81e98322c9a09c08b35d1095a25 Tree-SHA512: 9742aeeeabe8690530bf74caa6ba296787028c52f4a3342afd193b05dbbb1f6645935c33ba0a5230199a09af01c666bd3c7fb16b48692a0d185356ea59a8ddbf
2023-10-02test: Functional test for opportunistic encryptiondhruv
Co-authored-by: Pieter Wuille <bitcoin-dev@wuille.net>
2023-10-02net: expose transport types/session IDs of connections in RPC and logsPieter Wuille
Co-authored-by: Dhruv Mehta <856960+dhruv@users.noreply.github.com>
2023-10-02net: reconnect with V1Transport under certain conditionsPieter Wuille
When an outbound v2 connection is disconnected without receiving anything, but at least 24 bytes of our pubkey were sent out (enough to constitute an invalid v1 header), add them to a queue of reconnections to be tried. The reconnections are in a queue rather than performed immediately, because we should not block the socket handler thread with connection creation (a blocking operation that can take multiple seconds).
2023-10-02sync: modernize CSemaphore / CSemaphoreGrantPieter Wuille
2023-10-02rpc: addnode arg to use BIP324 v2 p2pdhruv
Co-authored-by: Pieter Wuille <bitcoin-dev@wuille.net>
2023-10-02net: use V2Transport when NODE_P2P_V2 service flag is presentPieter Wuille
Co-authored-by: Dhruv Mehta <856960+dhruv@users.noreply.github.com>
2023-10-02rpc: don't report v2 handshake bytes in the per-type sent byte statisticsSebastian Falbesoner
This matches the behavior for per-type received bytes.
2023-10-02Merge bitcoin/bitcoin#28508: refactor: Remove SER_GETHASH, hard-code client ↵fanquake
version in CKeyPool serialize fac29a0ab19fda457b55d7a0a37c5cd3d9680f82 Remove SER_GETHASH, hard-code client version in CKeyPool serialize (MarcoFalke) fa72f09d6ff8ee204f331a69d3f5e825223c9e11 Remove CHashWriter type (MarcoFalke) fa4a9c0f4334678fb80358ead667807bf2a0a153 Remove unused GetType() from OverrideStream, CVectorWriter, SpanReader (MarcoFalke) Pull request description: Removes a bunch of redundant, dead or duplicate code. Uses the idea from and finishes the idea https://github.com/bitcoin/bitcoin/pull/28428 by theuni ACKs for top commit: ajtowns: ACK fac29a0ab19fda457b55d7a0a37c5cd3d9680f82 kevkevinpal: added one nit but otherwise ACK [fac29a0](https://github.com/bitcoin/bitcoin/pull/28508/commits/fac29a0ab19fda457b55d7a0a37c5cd3d9680f82) Tree-SHA512: cc805e2f38e73869a6691fdb5da09fa48524506b87fc93f05d32c336ad3033425a2d7608e317decd3141fde3f084403b8de280396c0c39132336fe0f7510af9e
2023-09-27net: Simplify v2 recv logic by decoupling AAD from state machineTim Ruffing
2023-09-27net: Drop v2 garbage authentication packetTim Ruffing
See also https://github.com/bitcoin/bips/pull/1498 The benefit is a simpler implementation: - The protocol state machine does not need separate states for garbage authentication and version phases. - The special case of "ignoring the ignore bit" is removed. - The freedom to choose the contents of the garbage authentication packet is removed. This simplifies testing.
2023-09-21Merge bitcoin/bitcoin#28078: net, refactor: remove unneeded exports, use ↵Andrew Chow
helpers over low-level code, use optional 4ecfd3eaf434d868455466e001adae4b68515ab8 Inline short, often-called, rarely-changed basic CNetAddr getters (Jon Atack) 5316ae5dd8d90623f9bb883bb253fa6463ee4d34 Convert GetLocal() to std::optional and remove out-param (Jon Atack) f1304db136bbeac70b52522b5a4522165bfb3fc0 Use higher-level CNetAddr and CNode helpers in net.cpp (Jon Atack) 07f589158835151a7613e4b2a508c0dd61a18fd7 Add CNetAddr::IsPrivacyNet() and CNode::IsConnectedThroughPrivacyNet() (Jon Atack) df488563b280c63f5d74d5ac0fcb1a2cad489d55 GetLocal() type-safety, naming, const, and formatting cleanups (stickies-v) fb4265747c9eb022d80c6f2988e574c689130348 Add and use CNetAddr::HasCJDNSPrefix() helper (Jon Atack) 5ba73cd0ee1e661ec4d041ac8ae7a60cfd31f0c0 Move GetLocal() declaration from header to implementation (Jon Atack) 11426f6557ac09489d5e13bf3b9d94fbd5073c8e Move CaptureMessageToFile() declaration from header to implementation (Jon Atack) deccf1c4848620cfff2a9642c5a6b5acdfbc33bd Move IsPeerAddrLocalGood() declaration from header to implementation (Jon Atack) Pull request description: and other improvements noticed while reviewing #27411. Addresses https://github.com/bitcoin/bitcoin/pull/27411#discussion_r1263969104 and https://github.com/bitcoin/bitcoin/pull/27411#discussion_r1263967598. See commit messages for details. ACKs for top commit: achow101: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 vasild: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 stickies-v: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 Tree-SHA512: d792bb2cb24690aeae9bedf97e92b64fb6fd080c39385a4bdb8ed05f37f3134d85bda99da025490829c03017fd56382afe7951cdd039aede1c08ba98fb1aa7f9
2023-09-19Remove unused GetType() from OverrideStream, CVectorWriter, SpanReaderMarcoFalke
GetType() is never called, so it is completely unused and can be removed.
2023-09-15Merge bitcoin/bitcoin#28452: Do not use std::vector = {} to release memoryfanquake
3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e Do not use std::vector = {} to release memory (Pieter Wuille) Pull request description: It appears that invoking `v = {};` for an `std::vector<...> v` is equivalent to `v.clear()`, which does not release its allocated memory. There are a number of places in the codebase where it appears to be used for that purpose however (mostly written by me). Replace those with `std::vector<...>{}.swap(v);` (using a helper function `ClearShrink` in util/vector.h). To explain what is going on: `v = {...};` is equivalent in general to `v.operator=({...});`. For many types, the `{}` is converted to the type of `v`, and then assigned to `v` - which for `std::vector` would ordinarily have the effect of clearing its memory (constructing a new empty vector, and then move-assigning it to `v`). However, since `std::vector<T>` has an `operator=(std::initializer_list<T>)` defined, it has precedence (since no implicit conversion is needed), and with an empty list, that is equivalent to `clear()`. I did consider using `v = std::vector<T>{};` as replacement for `v = {};` instances where memory releasing is desired, but it appears that it does not actually work universally either. `V{}.swap(v);` does. ACKs for top commit: ajtowns: utACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e stickies-v: ACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e theStack: Code-review ACK 3fcd7fc7ff563bdc0e2bba66b4cbe72d898c876e Tree-SHA512: 6148558126ec3c8cfd6daee167ec1c67b360cf1dff2cbc132bd71768337cf9bc4dda3e5a9cf7da4f7457d2123288eeba77dd78f3a17fa2cfd9c6758262950cc5
2023-09-13Do not use std::vector = {} to release memoryPieter Wuille
2023-09-12[refactor] Remove netaddress.h from kernel headersTheCharlatan
Move functions requiring the netaddress.h include out of libbitcoinkernel source files. The netaddress.h file contains many non-consensus related definitions and should thus not be part of the libbitcoinkernel. This commit makes netaddress.h no longer a required include for users of the libbitcoinkernel. This commit is part of the libbitcoinkernel project, namely its stage 1 step 3: Decouple most non-consensus headers from libbitcoinkernel.
2023-09-12[refactor] Add CChainParams member to CConnmanTheCharlatan
This is done in preparation to the next commit, but has the nice effect of removing one further data structure relying on the global `Params()`.
2023-09-12kernel: Move MessageStartChars to its own fileTheCharlatan
The protocol.h file contains many non-consensus related definitions and should thus not be part of the libbitcoinkernel. This commit makes protocol.h no longer a required include for users of the libbitcoinkernel. This commit is part of the libbitcoinkernel project, namely its stage 1 step 3: Decouple most non-consensus headers from libbitcoinkernel. Co-Authored-By: Cory Fields <cory-nospam-@coryfields.com>
2023-09-12[refactor] Define MessageStartChars as std::arrayTheCharlatan
2023-09-10net: do not use send buffer to store/cache garbagePieter Wuille
Before this commit the V2Transport::m_send_buffer is used to store the garbage: * During MAYBE_V1 state, it's there despite not being sent. * During AWAITING_KEY state, while it is being sent. * At the end of the AWAITING_KEY state it cannot be wiped as it's still needed to compute the garbage authentication packet. Change this by introducing a separate m_send_garbage field, taking over the first and last role listed above. This means the garbage is only in the send buffer when it's actually being sent, removing a few special cases related to this.
2023-09-10net: merge V2Transport constructors, move key genPieter Wuille
This removes the ability for BIP324Cipher to generate its own key, moving that responsibility to the caller (mostly, V2Transport). This allows us to write the random-key V2Transport constructor by delegating to the explicit-key one.
2023-09-07net: detect wrong-network V1 talking to V2TransportPieter Wuille
2023-09-07net: make V2Transport preallocate receive buffer spacePieter Wuille
2023-09-07net: make V2Transport send uniformly random number garbage bytesPieter Wuille
2023-09-07net: add short message encoding/decoding support to V2TransportPieter Wuille
2023-09-07net: make V2Transport auto-detect incoming V1 and fall back to itPieter Wuille
2023-09-07net: add V2Transport class with subset of BIP324 functionalityPieter Wuille
This introduces a V2Transport with a basic subset of BIP324 functionality: * no ability to send garbage (but receiving is supported) * no ability to send decoy packets (but receiving them is supported) * no support for short message id encoding (neither encoding or decoding) * no waiting until 12 non-V1 bytes have been received * (and thus) no detection of V1 connections on the responder side (on the sender side, detecting V1 is not supported either, but that needs to be dealt with at a higher layer, by reconnecting)
2023-09-07net: add have_next_message argument to Transport::GetBytesToSend()Pieter Wuille
Before this commit, there are only two possibly outcomes for the "more" prediction in Transport::GetBytesToSend(): * true: the transport itself has more to send, so the answer is certainly yes. * false: the transport has nothing further to send, but if vSendMsg has more message(s) left, that still will result in more wire bytes after the next SetMessageToSend(). For the BIP324 v2 transport, there will arguably be a third state: * definitely not: the transport has nothing further to send, but even if vSendMsg has more messages left, they can't be sent (right now). This happens before the handshake is complete. To implement this, we move the entire decision logic to the Transport, by adding a boolean to GetBytesToSend(), called have_next_message, which informs the transport whether more messages are available. The return values are still true and false, but they mean "definitely yes" and "definitely no", rather than "yes" and "maybe".
2023-09-05Use serialization parameters for CAddress serializationMarcoFalke
This also cleans up the addrman (de)serialization code paths to only allow `Disk` serialization. Some unit tests previously forced a `Network` serialization, which does not make sense, because Bitcoin Core in production will always `Disk` serialize. This cleanup idea was suggested by Pieter Wuille and implemented by Anthony Towns. Co-authored-by: Pieter Wuille <pieter@wuille.net> Co-authored-by: Anthony Towns <aj@erisian.com.au>
2023-08-24net: don't check if the socket is valid in GetBindAddress()Vasil Dimov
The socket is always valid (the underlying file descriptor is not `INVALID_SOCKET`) when `GetBindAddress()` is called.
2023-08-23refactor: make Transport::ReceivedBytes just return success/failPieter Wuille
2023-08-23net: move message conversion to wire bytes from PushMessage to SocketSendDataPieter Wuille
This furthers transport abstraction by removing the assumption that a message can always immediately be converted to wire bytes. This assumption does not hold for the v2 transport proposed by BIP324, as no messages can be sent before the handshake completes. This is done by only keeping (complete) CSerializedNetMsg objects in vSendMsg, rather than the resulting bytes (for header and payload) that need to be sent. In SocketSendData, these objects are handed to the transport as permitted by it, and sending out the bytes the transport tells us to send. This also removes the nSendOffset member variable in CNode, as keeping track of how much has been sent is now a responsability of the transport. This is not a pure refactor, and has the following effects even for the current v1 transport: * Checksum calculation now happens in SocketSendData rather than PushMessage. For non-optimistic-send messages, that means this computation now happens in the network thread rather than the message handler thread (generally a good thing, as the message handler thread is more of a computational bottleneck). * Checksum calculation now happens while holding the cs_vSend lock. This is technically unnecessary for the v1 transport, as messages are encoded independent from one another, but is untenable for the v2 transport anyway. * Statistics updates about per-message sent bytes now happen when those bytes are actually handed to the OS, rather than at PushMessage time.
2023-08-23net: measure send buffer fullness based on memory usagePieter Wuille
This more accurately captures the intent of limiting send buffer size, as many small messages can have a larger overhead that is not counted with the current approach. It also means removing the dependency on the header size (which will become a function of the transport choice) from the send buffer calculations.
2023-08-23net: make V1Transport implicitly use current chainparamsPieter Wuille
The rest of net.cpp already uses Params() to determine chainparams in many places (and even V1Transport itself does so in some places). Since the only chainparams dependency is through the message start characters, just store those directly in the transport.
2023-08-23net: abstract sending side of transport serialization furtherPieter Wuille
This makes the sending side of P2P transports mirror the receiver side: caller provides message (consisting of type and payload) to be sent, and then asks what bytes must be sent. Once the message has been fully sent, a new message can be provided. This removes the assumption that P2P serialization of messages follows a strict structure of header (a function of type and payload), followed by (unmodified) payload, and instead lets transports decide the structure themselves. It also removes the assumption that a message must always be sent at once, or that no bytes are even sent on the wire when there is no message. This opens the door for supporting traffic shaping mechanisms in the future.