Skip to content

Commit b9f41df

Browse files
committed
Merge bitcoin#20685: Add I2P support using I2P SAM
a701fcf net: Do not skip the I2P network from GetNetworkNames() (Vasil Dimov) 0181e24 net: recognize I2P from ParseNetwork() so that -onlynet=i2p works (Vasil Dimov) b905363 net: accept incoming I2P connections from CConnman (Vasil Dimov) 0635233 net: make outgoing I2P connections from CConnman (Vasil Dimov) 9559bd1 net: add I2P to the reachability map (Vasil Dimov) 76c35c6 init: introduce I2P connectivity options (Vasil Dimov) c22daa2 net: implement the necessary parts of the I2P SAM protocol (Vasil Dimov) 5bac7e4 net: extend Sock with a method to check whether connected (Vasil Dimov) 42c779f net: extend Sock with methods for robust send & read until terminator (Vasil Dimov) ea18453 net: extend Sock::Wait() to report a timeout (Vasil Dimov) 78fdfbe net: dedup MSG_NOSIGNAL and MSG_DONTWAIT definitions (Vasil Dimov) 34bcfab net: move the constant maxWait out of InterruptibleRecv() (Vasil Dimov) cff65c4 net: extend CNetAddr::SetSpecial() to support I2P (Vasil Dimov) f6c267d net: avoid unnecessary GetBindAddress() call (Vasil Dimov) 7c224fd net: isolate the protocol-agnostic part of CConnman::AcceptConnection() (Vasil Dimov) 1f75a65 net: get the bind address earlier in CConnman::AcceptConnection() (Vasil Dimov) 2560589 net: check for invalid socket earlier in CConnman::AcceptConnection() (Vasil Dimov) 545bc5f util: fix WriteBinaryFile() claiming success even if error occurred (Vasil Dimov) 8b6e4b3 util: fix ReadBinaryFile() returning partial contents (Vasil Dimov) 4cba2fd util: extract {Read,Write}BinaryFile() to its own files (Vasil Dimov) Pull request description: Add I2P support by using the [I2P SAM](https://geti2p.net/en/docs/api/samv3) protocol. Unlike Tor, for incoming connections we get the I2P address of the peer (and they also receive ours when we are the connection initiator). Two new options are added: ``` -i2psam=<ip:port> I2P SAM proxy to reach I2P peers and accept I2P connections (default: none) -i2pacceptincoming If set and -i2psam is also set then incoming I2P connections are accepted via the SAM proxy. If this is not set but -i2psam is set then only outgoing connections will be made to the I2P network. Ignored if -i2psam is not set. Notice that listening for incoming I2P connections is done through the SAM proxy, not by binding to a local address and port (default: true) ``` # Overview of the changes ## Make `ReadBinary()` and `WriteBinary()` reusable We would need to dump the I2P private key to a file and read it back later. Move those two functions out of `torcontrol.cpp`. ``` util: extract {Read,Write}BinaryFile() to its own files util: fix ReadBinaryFile() returning partial contents util: fix WriteBinaryFile() claiming success even if error occurred ``` ## Split `CConnman::AcceptConnection()` Most of `CConnman::AcceptConnection()` is agnostic of how the socket was accepted. The other part of it deals with the details of the `accept(2)` system call. Split those so that the protocol-agnostic part can be reused if we accept a socket by other means. ``` net: check for invalid socket earlier in CConnman::AcceptConnection() net: get the bind address earlier in CConnman::AcceptConnection() net: isolate the protocol-agnostic part of CConnman::AcceptConnection() net: avoid unnecessary GetBindAddress() call ``` ## Implement the I2P [SAM](https://geti2p.net/en/docs/api/samv3) protocol (not all of it) Just the parts that would enable us to make outgoing and accept incoming I2P connections. ``` net: extend CNetAddr::SetSpecial() to support I2P net: move the constant maxWait out of InterruptibleRecv() net: dedup MSG_NOSIGNAL and MSG_DONTWAIT definitions net: extend Sock::Wait() to report a timeout net: extend Sock with methods for robust send & read until terminator net: extend Sock with a method to check whether connected net: implement the necessary parts of the I2P SAM protocol ``` ## Use I2P SAM to connect to and accept connections from I2P peers Profit from all of the preceding commits. ``` init: introduce I2P connectivity options net: add I2P to the reachability map net: make outgoing I2P connections from CConnman net: accept incoming I2P connections from CConnman net: recognize I2P from ParseNetwork() so that -onlynet=i2p works net: Do not skip the I2P network from GetNetworkNames() ``` ACKs for top commit: laanwj: re-ACK a701fcf jonatack: re-ACK a701fcf reviewed diff per `git range-diff ad89812 2a7bb34 a701fcf`, debug built and launched bitcoind with i2pd v2.35 running a dual I2P+Torv3 service with the I2P config settings listed below (did not test `onlynet=i2p`); operation appears nominal (same as it has been these past weeks), and tested the bitcoind help outputs grepping for `-i i2p` and the rpc getpeerinfo and getnetworkinfo helps Tree-SHA512: de42090c9c0bf23b43b5839f5b4fc4b3a2657bde1e45c796b5f3c7bf83cb8ec6ca4278f8a89e45108ece92f9b573cafea3b42a06bc09076b40a196c909b6610e
2 parents cfce346 + a701fcf commit b9f41df

22 files changed

+1304
-113
lines changed

doc/files.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Subdirectory | File(s) | Description
6464
`./` | `ip_asn.map` | IP addresses to Autonomous System Numbers (ASNs) mapping used for bucketing of the peers; path can be specified with the `-asmap` option
6565
`./` | `mempool.dat` | Dump of the mempool's transactions
6666
`./` | `onion_v3_private_key` | Cached Tor onion service private key for `-listenonion` option
67+
`./` | `i2p_private_key` | Private key that corresponds to our I2P address. When `-i2psam=` is specified the contents of this file is used to identify ourselves for making outgoing connections to I2P peers and possibly accepting incoming ones. Automatically generated if it does not exist.
6768
`./` | `peers.dat` | Peer IP address database (custom format)
6869
`./` | `settings.json` | Read-write settings set through GUI or RPC interfaces, augmenting manual settings from [bitcoin.conf](bitcoin-conf.md). File is created automatically if read-write settings storage is not disabled with `-nosettings` option. Path can be specified with `-settings` option
6970
`./` | `.cookie` | Session RPC authentication cookie; if used, created at start and deleted on shutdown; can be specified by `-rpccookiefile` option

src/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ BITCOIN_CORE_H = \
148148
fs.h \
149149
httprpc.h \
150150
httpserver.h \
151+
i2p.h \
151152
index/base.h \
152153
index/blockfilterindex.h \
153154
index/disktxpos.h \
@@ -242,6 +243,7 @@ BITCOIN_CORE_H = \
242243
util/message.h \
243244
util/moneystr.h \
244245
util/rbf.h \
246+
util/readwritefile.h \
245247
util/ref.h \
246248
util/settings.h \
247249
util/sock.h \
@@ -314,6 +316,7 @@ libbitcoin_server_a_SOURCES = \
314316
flatfile.cpp \
315317
httprpc.cpp \
316318
httpserver.cpp \
319+
i2p.cpp \
317320
index/base.cpp \
318321
index/blockfilterindex.cpp \
319322
index/txindex.cpp \
@@ -572,6 +575,7 @@ libbitcoin_util_a_SOURCES = \
572575
util/message.cpp \
573576
util/moneystr.cpp \
574577
util/rbf.cpp \
578+
util/readwritefile.cpp \
575579
util/settings.cpp \
576580
util/threadnames.cpp \
577581
util/spanparsing.cpp \

src/compat.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,22 @@ typedef unsigned int SOCKET;
4444
#define WSAEINVAL EINVAL
4545
#define WSAEALREADY EALREADY
4646
#define WSAEWOULDBLOCK EWOULDBLOCK
47+
#define WSAEAGAIN EAGAIN
4748
#define WSAEMSGSIZE EMSGSIZE
4849
#define WSAEINTR EINTR
4950
#define WSAEINPROGRESS EINPROGRESS
5051
#define WSAEADDRINUSE EADDRINUSE
5152
#define WSAENOTSOCK EBADF
5253
#define INVALID_SOCKET (SOCKET)(~0)
5354
#define SOCKET_ERROR -1
55+
#else
56+
#ifndef WSAEAGAIN
57+
#ifdef EAGAIN
58+
#define WSAEAGAIN EAGAIN
59+
#else
60+
#define WSAEAGAIN WSAEWOULDBLOCK
61+
#endif
62+
#endif
5463
#endif
5564

5665
#ifdef WIN32
@@ -96,4 +105,14 @@ bool static inline IsSelectableSocket(const SOCKET& s) {
96105
#endif
97106
}
98107

108+
// MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
109+
#if !defined(MSG_NOSIGNAL)
110+
#define MSG_NOSIGNAL 0
111+
#endif
112+
113+
// MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
114+
#if !defined(MSG_DONTWAIT)
115+
#define MSG_DONTWAIT 0
116+
#endif
117+
99118
#endif // BITCOIN_COMPAT_H

0 commit comments

Comments
 (0)