forked from such-gitea/wownero
Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c40ab9b5be | ||
|
|
ae681a9bb3 | ||
|
|
998bf82f24 | ||
|
|
0f61e39eea | ||
|
|
33743eb7ac | ||
|
|
46f3d3e975 | ||
|
|
2842f81b80 | ||
|
|
1b5cefac03 | ||
|
|
8fdd38c48c | ||
|
|
078c84ed72 | ||
|
|
99bf440290 | ||
|
|
4cec4db7f0 | ||
|
|
3b97d399b1 | ||
|
|
a23468af8c | ||
|
|
38c49b7a35 | ||
|
|
e4ddf841ee | ||
|
|
48b97fe5c7 | ||
|
|
9a99788660 | ||
|
|
c93ef4369c | ||
|
|
541c3b069a | ||
|
|
1ee249435e | ||
|
|
3f94fe0c4f | ||
|
|
af89312d24 | ||
|
|
6717051efd | ||
|
|
1d39aba9b8 | ||
|
|
8d5032a39f | ||
|
|
90e116ea3d | ||
|
|
5dfa3c1244 | ||
|
|
ca9ae12d5b | ||
|
|
dbaa1b9e68 | ||
|
|
28cdfd7c1c | ||
|
|
e7de8aa9dc | ||
|
|
9fb892adbe | ||
|
|
3553a9d8f5 | ||
|
|
2cc3960bfc | ||
|
|
0009b32f08 | ||
|
|
26ff420531 | ||
|
|
870b4138a6 | ||
|
|
683cde52f7 | ||
|
|
d498b2d791 | ||
|
|
df637cd08c | ||
|
|
46441d7c23 | ||
|
|
f82747320d | ||
|
|
d2ec59ca20 | ||
|
|
f44faf1b20 | ||
|
|
ff57e849d4 | ||
|
|
9e36058618 | ||
|
|
d658094761 | ||
|
|
d91f84f275 | ||
|
|
e51164f259 | ||
|
|
5a71ea66ef | ||
|
|
103ee1f2cc | ||
|
|
38b33944b5 | ||
|
|
b254539efb | ||
|
|
3ebc478967 | ||
|
|
31f9c9a3c9 | ||
|
|
9adc9b4a09 | ||
|
|
6c77e9e4ea | ||
|
|
cd0b5a1a4c | ||
|
|
31abdddd1b | ||
|
|
8746a9b379 | ||
|
|
de74b2590d | ||
|
|
32007ea554 | ||
|
|
e5bcff2def | ||
|
|
d52f27f568 | ||
|
|
84ca8550d2 | ||
|
|
2f4f8b1380 | ||
|
|
da885c041a | ||
|
|
37430e0a5b | ||
|
|
7bce433b89 | ||
|
|
f796a2dac4 | ||
|
|
111e25f10d | ||
|
|
dd2eca2126 | ||
|
|
4c5812b899 | ||
|
|
6ef6d5aa8b | ||
|
|
0b29a3e2c4 | ||
|
|
1f79072d19 | ||
|
|
c5d00f4e29 | ||
|
|
76a61ab006 | ||
|
|
9f9653cbc0 | ||
|
|
65940b75f7 | ||
|
|
0138a9a2b9 | ||
|
|
b0fda7c551 | ||
|
|
d50f2f5ac1 | ||
|
|
9a82e73e5d | ||
|
|
816c223a05 | ||
|
|
3c561f3bfc | ||
|
|
8cafa0bc1c | ||
|
|
dd280789cd | ||
|
|
fef9c01bb7 | ||
|
|
935831a7f9 | ||
|
|
d81e9178b8 | ||
|
|
d140d13603 | ||
|
|
87300a2f6a | ||
|
|
d41415ec48 | ||
|
|
4f8c3b771f | ||
|
|
7e339ea873 | ||
|
|
0acdc0fe0c | ||
|
|
35d09f896b | ||
|
|
64c7ced3ed | ||
|
|
e543d779d8 | ||
|
|
99533d4592 | ||
|
|
79d614652a | ||
|
|
59614f874a | ||
|
|
7ea53abfdf | ||
|
|
e3718d7c03 | ||
|
|
314e24d0ff | ||
|
|
fb3f6e723d | ||
|
|
ccaffcfbb5 | ||
|
|
6f53b0f14e | ||
|
|
b925e9417c | ||
|
|
b2cb640b11 | ||
|
|
3f4fc508ff | ||
|
|
c0691dfc25 | ||
|
|
1151ce6e6b | ||
|
|
880d14db91 | ||
|
|
d0953fb2b7 | ||
|
|
a9ef699472 | ||
|
|
bfd24d58c6 | ||
|
|
267e656d8b | ||
|
|
a17a81b3a7 | ||
|
|
e789d7c324 | ||
|
|
83072c2165 | ||
|
|
4411a412be | ||
|
|
2de45b2c0e | ||
|
|
2439d2a39d | ||
|
|
d85d908ddc | ||
|
|
6cbafa9dd9 | ||
|
|
842bcffbb8 | ||
|
|
c946a35985 | ||
|
|
41e12d4d29 | ||
|
|
c7d4338765 | ||
|
|
6c76c778e7 | ||
|
|
34daa571e3 | ||
|
|
70e4e4382e | ||
|
|
af2d19cf70 | ||
|
|
28477c75a3 | ||
|
|
f875a0312e | ||
|
|
0030100645 | ||
|
|
0c87b55670 | ||
|
|
70d90326a7 | ||
|
|
76c97e4dbc | ||
|
|
4422b14ac0 | ||
|
|
aad10a6cb0 | ||
|
|
ed5b588ca3 | ||
|
|
9eedf5f087 | ||
|
|
8ef2437e5d | ||
|
|
e2095e00ba | ||
|
|
b494943a10 | ||
|
|
d40acef20b | ||
|
|
36da8397f8 | ||
|
|
7bb6c00b5e | ||
|
|
f97b2edb3c | ||
|
|
1b0fe29ee3 | ||
|
|
c3fae517a4 | ||
|
|
442b30eee9 | ||
|
|
8f7add0a05 | ||
|
|
e1355ecd3e | ||
|
|
a44d54645e | ||
|
|
be87172237 | ||
|
|
4bd63dab9d | ||
|
|
a121320fc9 | ||
|
|
10d79d1848 | ||
|
|
9736a0a8b9 | ||
|
|
0ad6583329 | ||
|
|
636ffdc7a1 | ||
|
|
e55621dbd2 | ||
|
|
88735bd65b | ||
|
|
47f0f9b3f4 | ||
|
|
ecaf564d38 | ||
|
|
0ef925d131 | ||
|
|
0a1ca3a329 | ||
|
|
bdf6f05418 | ||
|
|
31a47b6638 | ||
|
|
76c2cb0771 | ||
|
|
9427077649 | ||
|
|
40d658a327 | ||
|
|
6c204bba0a | ||
|
|
4ba5309da0 | ||
|
|
751c6beca2 | ||
|
|
cf94656674 | ||
|
|
d984bd95d7 | ||
|
|
23b1e28b8d | ||
|
|
e33ff94cc0 | ||
|
|
e94ca47010 | ||
|
|
929e210ad2 | ||
|
|
9f2ea08a8e | ||
|
|
50fea66409 | ||
|
|
61d21bd236 | ||
|
|
ec18a0df32 | ||
|
|
2b66b27fe5 | ||
|
|
98031957e1 | ||
|
|
2d759a17a8 | ||
|
|
92f7de3d62 | ||
|
|
c786fb5a13 | ||
|
|
2e6174addd | ||
|
|
afc77b45ba | ||
|
|
48ef3ff466 | ||
|
|
e011f7ac47 | ||
|
|
1a8353dd90 | ||
|
|
28100fbd68 | ||
|
|
389d2bc53e | ||
|
|
79d38f3bdd | ||
|
|
8e428f8ef6 | ||
|
|
27c0af7295 | ||
|
|
7ae7796866 | ||
|
|
1104a17246 | ||
|
|
72904ee107 | ||
|
|
65d056aeae | ||
|
|
fbc506b1f5 | ||
|
|
54040da1a1 | ||
|
|
10b7f2b45f | ||
|
|
7759d52a25 | ||
|
|
5bf7ce14c5 | ||
|
|
7e93cdba07 | ||
|
|
c9bec32aa0 | ||
|
|
76c7878dea | ||
|
|
57e8fce462 | ||
|
|
b58f12e53e | ||
|
|
8ac7ba7d99 | ||
|
|
d9649d98cd | ||
|
|
61f3a191df | ||
|
|
675b879844 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -12,6 +12,3 @@
|
||||
[submodule "external/trezor-common"]
|
||||
path = external/trezor-common
|
||||
url = https://github.com/trezor/trezor-common.git
|
||||
[submodule "external/randomwow"]
|
||||
path = external/randomwow
|
||||
url = https://github.com/wownero/RandomWOW
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -10,12 +10,16 @@ cache:
|
||||
env:
|
||||
global:
|
||||
- MAKEJOBS=-j3
|
||||
- RUN_TESTS=false
|
||||
- BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
|
||||
- CCACHE_SIZE=100M
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
- CCACHE_DIR=$HOME/.ccache
|
||||
- BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
|
||||
- SDK_URL=https://bitcoincore.org/depends-sources/sdks
|
||||
- PYTHON_DEBUG=1
|
||||
- WINEDEBUG=fixme-all
|
||||
- DOCKER_PACKAGES="build-essential libtool cmake autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache"
|
||||
matrix:
|
||||
# ARM v7
|
||||
@@ -23,20 +27,20 @@ env:
|
||||
# ARM v8
|
||||
- HOST=aarch64-linux-gnu PACKAGES="python3 gperf g++-aarch64-linux-gnu"
|
||||
# i686 Win
|
||||
- HOST=i686-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="python3 g++-mingw-w64-i686 qttools5-dev-tools"
|
||||
- HOST=i686-w64-mingw32 PACKAGES="python3 nsis g++-mingw-w64-i686"
|
||||
# i686 Linux
|
||||
- HOST=i686-pc-linux-gnu PACKAGES="gperf cmake g++-multilib python3-zmq"
|
||||
- HOST=i686-pc-linux-gnu PACKAGES="gperf cmake g++-multilib bc python3-zmq" RUN_TESTS=true
|
||||
# Win64
|
||||
- HOST=x86_64-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="cmake python3 g++-mingw-w64-x86-64 qttools5-dev-tools"
|
||||
- HOST=x86_64-w64-mingw32 PACKAGES="cmake python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64 bc" RUN_TESTS=true
|
||||
# x86_64 Linux
|
||||
- HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev"
|
||||
- HOST=x86_64-unknown-linux-gnu PACKAGES="gperf cmake python3-zmq libdbus-1-dev libharfbuzz-dev" RUN_TESTS=true
|
||||
# Cross-Mac
|
||||
- HOST=x86_64-apple-darwin11 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.11
|
||||
|
||||
before_install:
|
||||
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
|
||||
install:
|
||||
- env | grep -E '^(CCACHE_|DISPLAY|CONFIG_SHELL)' | tee /tmp/env
|
||||
- env | grep -E '^(CCACHE_|WINEDEBUG|DISPLAY|BOOST_TEST_RANDOM|CONFIG_SHELL)' | tee /tmp/env
|
||||
- if [[ $HOST = *-mingw32 ]]; then DOCKER_ADMIN="--cap-add SYS_ADMIN"; fi
|
||||
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env ubuntu:18.04)
|
||||
- DOCKER_EXEC="docker exec $DOCKER_ID"
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
# Anonymity Networks with Monero
|
||||
|
||||
Currently only Tor and I2P have been integrated into Monero. The usage of
|
||||
these networks is still considered experimental - there are a few pessimistic
|
||||
cases where privacy is leaked. The design is intended to maximize privacy of
|
||||
the source of a transaction by broadcasting it over an anonymity network, while
|
||||
relying on IPv4 for the remainder of messages to make surrounding node attacks
|
||||
(via sybil) more difficult.
|
||||
|
||||
|
||||
## Behavior
|
||||
|
||||
If _any_ anonymity network is enabled, transactions being broadcast that lack
|
||||
a valid "context" (i.e. the transaction did not come from a p2p connection),
|
||||
will only be sent to peers on anonymity networks. If an anonymity network is
|
||||
enabled but no peers over an anonymity network are available, an error is
|
||||
logged and the transaction is kept for future broadcasting over an anonymity
|
||||
network. The transaction will not be broadcast unless an anonymity connection
|
||||
is made or until `monerod` is shutdown and restarted with only public
|
||||
connections enabled.
|
||||
|
||||
Anonymity networks can also be used with `monero-wallet-cli` and
|
||||
`monero-wallet-rpc` - the wallets will connect to a daemon through a proxy. The
|
||||
daemon must provide a hidden service for the RPC itself, which is separate from
|
||||
the hidden service for P2P connections.
|
||||
|
||||
|
||||
## P2P Commands
|
||||
|
||||
Only handshakes, peer timed syncs and transaction broadcast messages are
|
||||
supported over anonymity networks. If one `--add-exclusive-node` p2p address
|
||||
is specified, then no syncing will take place and only transaction broadcasting
|
||||
can occur. It is therefore recommended that `--add-exclusive-node` be combined
|
||||
with additional exclusive IPv4 address(es).
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Anonymity networks have no seed nodes (the feature is still considered
|
||||
experimental), so a user must specify an address. If configured properly,
|
||||
additional peers can be found through typical p2p peerlist sharing.
|
||||
|
||||
### Outbound Connections
|
||||
|
||||
Connecting to an anonymous address requires the command line option
|
||||
`--proxy` which tells `monerod` the ip/port of a socks proxy provided by a
|
||||
separate process. On most systems the configuration will look like:
|
||||
|
||||
> `--proxy tor,127.0.0.1:9050,10`
|
||||
> `--proxy i2p,127.0.0.1:9000`
|
||||
|
||||
which tells `monerod` that ".onion" p2p addresses can be forwarded to a socks
|
||||
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
|
||||
".b32.i2p" p2p addresses can be forwarded to a socks proxy at IP 127.0.0.1 port
|
||||
9000 with the default max outgoing connections. Since there are no seed nodes
|
||||
for anonymity connections, peers must be manually specified:
|
||||
|
||||
> `--add-exclusive-node rveahdfho7wo4b2m.onion:28083`
|
||||
> `--add-peer rveahdfho7wo4b2m.onion:28083`
|
||||
|
||||
Either option can be listed multiple times, and can specify any mix of Tor,
|
||||
I2P, and IPv4 addresses. Using `--add-exclusive-node` will prevent the usage of
|
||||
seed nodes on ALL networks, which will typically be undesireable.
|
||||
|
||||
### Inbound Connections
|
||||
|
||||
Receiving anonymity connections is done through the option
|
||||
`--anonymous-inbound`. This option tells `monerod` the inbound address, network
|
||||
type, and max connections:
|
||||
|
||||
> `--anonymous-inbound rveahdfho7wo4b2m.onion:28083,127.0.0.1:28083,25`
|
||||
> `--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000,127.0.0.1:30000`
|
||||
|
||||
which tells `monerod` that a max of 25 inbound Tor connections are being
|
||||
received at address "rveahdfho7wo4b2m.onion:28083" and forwarded to `monerod`
|
||||
localhost port 28083, and a default max I2P connections are being received at
|
||||
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p:5000" and
|
||||
forwarded to `monerod` localhost port 30000.
|
||||
These addresses will be shared with outgoing peers, over the same network type,
|
||||
otherwise the peer will not be notified of the peer address by the proxy.
|
||||
|
||||
### Wallet RPC
|
||||
|
||||
An anonymity network can be configured to forward incoming connections to a
|
||||
`monerod` RPC port - which is independent from the configuration for incoming
|
||||
P2P anonymity connections. The anonymity network (Tor/i2p) is
|
||||
[configured in the same manner](#configuration), except the localhost port
|
||||
must be the RPC port (typically 18081 for mainnet) instead of the p2p port:
|
||||
|
||||
> HiddenServiceDir /var/lib/tor/data/monero
|
||||
> HiddenServicePort 18081 127.0.0.1:18081
|
||||
|
||||
Then the wallet will be configured to use a Tor/i2p address:
|
||||
> `--proxy 127.0.0.1:9050`
|
||||
> `--daemon-address rveahdfho7wo4b2m.onion`
|
||||
|
||||
The proxy must match the address type - a Tor proxy will not work properly with
|
||||
i2p addresses, etc.
|
||||
|
||||
i2p and onion addresses provide the information necessary to authenticate and
|
||||
encrypt the connection from end-to-end. If desired, SSL can also be applied to
|
||||
the connection with `--daemon-address https://rveahdfho7wo4b2m.onion` which
|
||||
requires a server certificate that is signed by a "root" certificate on the
|
||||
machine running the wallet. Alternatively, `--daemon-cert-file` can be used to
|
||||
specify a certificate to authenticate the server.
|
||||
|
||||
Proxies can also be used to connect to "clearnet" (ipv4 addresses or ICANN
|
||||
domains), but `--daemon-cert-file` _must_ be used for authentication and
|
||||
encryption.
|
||||
|
||||
### Network Types
|
||||
|
||||
#### Tor & I2P
|
||||
|
||||
Options `--add-exclusive-node` and `--add-peer` recognize ".onion" and
|
||||
".b32.i2p" addresses, and will properly forward those addresses to the proxy
|
||||
provided with `--proxy tor,...` or `--proxy i2p,...`.
|
||||
|
||||
Option `--anonymous-inbound` also recognizes ".onion" and ".b32.i2p" addresses,
|
||||
and will automatically be sent out to outgoing Tor/I2P connections so the peer
|
||||
can distribute the address to its other peers.
|
||||
|
||||
##### Configuration
|
||||
|
||||
Tor must be configured for hidden services. An example configuration ("torrc")
|
||||
might look like:
|
||||
|
||||
> HiddenServiceDir /var/lib/tor/data/monero
|
||||
> HiddenServicePort 28083 127.0.0.1:28083
|
||||
|
||||
This will store key information in `/var/lib/tor/data/monero` and will forward
|
||||
"Tor port" 28083 to port 28083 of ip 127.0.0.1. The file
|
||||
`/usr/lib/tor/data/monero/hostname` will contain the ".onion" address for use
|
||||
with `--anonymous-inbound`.
|
||||
|
||||
I2P must be configured with a standard server tunnel. Configuration differs by
|
||||
I2P implementation.
|
||||
|
||||
## Privacy Limitations
|
||||
|
||||
There are currently some techniques that could be used to _possibly_ identify
|
||||
the machine that broadcast a transaction over an anonymity network.
|
||||
|
||||
### Timestamps
|
||||
|
||||
The peer timed sync command sends the current time in the message. This value
|
||||
can be used to link an onion address to an IPv4/IPv6 address. If a peer first
|
||||
sees a transaction over Tor, it could _assume_ (possibly incorrectly) that the
|
||||
transaction originated from the peer. If both the Tor connection and an
|
||||
IPv4/IPv6 connection have timestamps that are approximately close in value they
|
||||
could be used to link the two connections. This is less likely to happen if the
|
||||
system clock is fairly accurate - many peers on the Monero network should have
|
||||
similar timestamps.
|
||||
|
||||
#### Mitigation
|
||||
|
||||
Keep the system clock accurate so that fingerprinting is more difficult. In
|
||||
the future a random offset might be applied to anonymity networks so that if
|
||||
the system clock is noticeably off (and therefore more fingerprintable),
|
||||
linking the public IPv4/IPv6 connections with the anonymity networks will be
|
||||
more difficult.
|
||||
|
||||
### Bandwidth Usage
|
||||
|
||||
An ISP can passively monitor `monerod` connections from a node and observe when
|
||||
a transaction is sent over a Tor/I2P connection via timing analysis + size of
|
||||
data sent during that timeframe. I2P should provide better protection against
|
||||
this attack - its connections are not circuit based. However, if a node is
|
||||
only using I2P for broadcasting Monero transactions, the total aggregate of
|
||||
I2P data would also leak information.
|
||||
|
||||
#### Mitigation
|
||||
|
||||
There is no current mitigation for the user right now. This attack is fairly
|
||||
sophisticated, and likely requires support from the internet host of a Monero
|
||||
user.
|
||||
|
||||
In the near future, "whitening" the amount of data sent over anonymity network
|
||||
connections will be performed. An attempt will be made to make a transaction
|
||||
broadcast indistinguishable from a peer timed sync command.
|
||||
|
||||
### Intermittent Monero Syncing
|
||||
|
||||
If a user only runs `monerod` to send a transaction then quit, this can also
|
||||
be used by an ISP to link a user to a transaction.
|
||||
|
||||
#### Mitigation
|
||||
|
||||
Run `monerod` as often as possible to conceal when transactions are being sent.
|
||||
Future versions will also have peers that first receive a transaction over an
|
||||
anonymity network delay the broadcast to public peers by a randomized amount.
|
||||
This will not completetely mitigate a user who syncs up sends then quits, in
|
||||
part because this rule is not enforceable, so this mitigation strategy is
|
||||
simply a best effort attempt.
|
||||
|
||||
### Active Bandwidth Shaping
|
||||
|
||||
An attacker could attempt to bandwidth shape traffic in an attempt to determine
|
||||
the source of a Tor/I2P connection. There isn't great mitigation against
|
||||
this, but I2P should provide better protection against this attack since
|
||||
the connections are not circuit based.
|
||||
|
||||
#### Mitigation
|
||||
|
||||
The best mitigiation is to use I2P instead of Tor. However, I2P
|
||||
has a smaller set of users (less cover traffic) and academic reviews, so there
|
||||
is a tradeoff in potential isses. Also, anyone attempting this strategy really
|
||||
wants to uncover a user, it seems unlikely that this would be performed against
|
||||
every Tor/I2P user.
|
||||
|
||||
@@ -44,8 +44,6 @@ message(STATUS "CMake version ${CMAKE_VERSION}")
|
||||
|
||||
project(monero)
|
||||
|
||||
enable_language(C ASM)
|
||||
|
||||
function (die msg)
|
||||
if (NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
@@ -115,9 +113,6 @@ string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||
# to identify the target architecture, to direct logic in this cmake script.
|
||||
# Since ARCH is a cached variable, it will not be set on first cmake invocation.
|
||||
if (NOT ARCH OR ARCH STREQUAL "" OR ARCH STREQUAL "native" OR ARCH STREQUAL "default")
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "")
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
set(ARCH_ID "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
else()
|
||||
set(ARCH_ID "${ARCH}")
|
||||
@@ -205,7 +200,6 @@ if(NOT MANUAL_SUBMODULES)
|
||||
check_submodule(external/unbound)
|
||||
check_submodule(external/rapidjson)
|
||||
check_submodule(external/trezor-common)
|
||||
check_submodule(external/randomwow)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -710,6 +704,7 @@ else()
|
||||
endif()
|
||||
|
||||
if(BACKCOMPAT)
|
||||
add_definitions(-DFDELT_TYPE=long\ int)
|
||||
add_linker_flag_if_supported(-Wl,--wrap=__divmoddi4 LD_BACKCOMPAT_FLAGS)
|
||||
add_linker_flag_if_supported(-Wl,--wrap=glob LD_BACKCOMPAT_FLAGS)
|
||||
message(STATUS "Using Lib C back compat flags: ${LD_BACKCOMPAT_FLAGS}")
|
||||
@@ -896,7 +891,6 @@ set(OLD_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
if(STATIC)
|
||||
if(MINGW)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
endif()
|
||||
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
@@ -906,19 +900,13 @@ find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
|
||||
if(NOT Boost_FOUND)
|
||||
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (>=1.58) or the equivalent")
|
||||
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.58) or the equivalent")
|
||||
elseif(Boost_FOUND)
|
||||
message(STATUS "Found Boost Version: ${Boost_VERSION}")
|
||||
if (Boost_VERSION VERSION_LESS 10 AND Boost_VERSION VERSION_LESS 1.62.0 AND NOT (OPENSSL_VERSION VERSION_LESS 1.1))
|
||||
set(BOOST_BEFORE_1_62 true)
|
||||
endif()
|
||||
if (NOT Boost_VERSION VERSION_LESS 10 AND Boost_VERSION VERSION_LESS 106200 AND NOT (OPENSSL_VERSION VERSION_LESS 1.1))
|
||||
set(BOOST_BEFORE_1_62 true)
|
||||
endif()
|
||||
if (BOOST_BEFORE_1_62)
|
||||
message(FATAL_ERROR "Boost ${Boost_VERSION} (older than 1.62) is too old to link with OpenSSL ${OPENSSL_VERSION} (1.1 or newer) found at ${OPENSSL_INCLUDE_DIR} and ${OPENSSL_LIBRARIES}. "
|
||||
if (Boost_VERSION VERSION_LESS 106200 AND NOT (OPENSSL_VERSION VERSION_LESS 1.1))
|
||||
message(FATAL_ERROR "Boost older than 1.62 is too old to link with OpenSSL 1.1 or newer. "
|
||||
"Update Boost or install OpenSSL 1.0 and set path to it when running cmake: "
|
||||
"cmake -DOPENSSL_ROOT_DIR='/usr/include/openssl-1.0'")
|
||||
"cmake -DOPENSSL_ROOT_DIR='/usr/include/openssl-1.0;/usr/lib/openssl-1.0'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -927,7 +915,7 @@ if(MINGW)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
|
||||
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt)
|
||||
if(DEPENDS)
|
||||
set(ICU_LIBRARIES icuio icui18n icuuc icudata icutu iconv)
|
||||
set(ICU_LIBRARIES sicuio sicuin sicuuc sicudt sicutu iconv)
|
||||
else()
|
||||
set(ICU_LIBRARIES icuio icuin icuuc icudt icutu iconv)
|
||||
endif()
|
||||
@@ -1047,5 +1035,3 @@ option(INSTALL_VENDORED_LIBUNBOUND "Install libunbound binary built from source
|
||||
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-std=c11 HAVE_C11)
|
||||
|
||||
find_package(PythonInterp)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Portions Copyright (c) 2017-2019, The Monero Project
|
||||
# Portions Copyright (c) 2017-2018, The Monero Project
|
||||
# This file is based off of the https://code.google.com/archive/p/ios-cmake/
|
||||
# It has been altered for Monero iOS development
|
||||
#
|
||||
|
||||
@@ -88,26 +88,26 @@ C4 is meant to provide a reusable optimal collaboration model for open source so
|
||||
|
||||
### Preliminaries
|
||||
|
||||
- The project MUST use the git distributed revision control system.
|
||||
- The project MUST be hosted on github.com or equivalent, herein called the "Platform".
|
||||
- The project MUST use the Platform issue tracker.
|
||||
- The project SHALL use the git distributed revision control system.
|
||||
- The project SHALL be hosted on github.com or equivalent, herein called the "Platform".
|
||||
- The project SHALL use the Platform issue tracker.
|
||||
- Non-GitHub example:
|
||||
- "Platform" could be a vanilla git repo and Trac hosted on the same machine/network.
|
||||
- The Platform issue tracker would be Trac.
|
||||
- The project SHOULD have clearly documented guidelines for code style.
|
||||
- A "Contributor" is a person who wishes to provide a patch, being a set of commits that solve some clearly identified problem.
|
||||
- A "Maintainer" is a person who merges patches to the project. Maintainers are not developers; their job is to enforce process.
|
||||
- Contributors MUST NOT have commit access to the repository unless they are also Maintainers.
|
||||
- Maintainers MUST have commit access to the repository.
|
||||
- Everyone, without distinction or discrimination, MUST have an equal right to become a Contributor under the terms of this contract.
|
||||
- Contributors SHALL NOT have commit access to the repository unless they are also Maintainers.
|
||||
- Maintainers SHALL have commit access to the repository.
|
||||
- Everyone, without distinction or discrimination, SHALL have an equal right to become a Contributor under the terms of this contract.
|
||||
|
||||
### Licensing and ownership
|
||||
|
||||
- The project MUST use a share-alike license, such as BSD-3, the GPLv3 or a variant thereof (LGPL, AGPL), or the MPLv2.
|
||||
- All contributions to the project source code ("patches") MUST use the same license as the project.
|
||||
- All patches are owned by their authors. There MUST NOT be any copyright assignment process.
|
||||
- The copyrights in the project MUST be owned collectively by all its Contributors.
|
||||
- Each Contributor MUST be responsible for identifying themselves in the project Contributor list.
|
||||
- The project SHALL use a share-alike license, such as BSD-3, the GPLv3 or a variant thereof (LGPL, AGPL), or the MPLv2.
|
||||
- All contributions to the project source code ("patches") SHALL use the same license as the project.
|
||||
- All patches are owned by their authors. There SHALL NOT be any copyright assignment process.
|
||||
- The copyrights in the project SHALL be owned collectively by all its Contributors.
|
||||
- Each Contributor SHALL be responsible for identifying themselves in the project Contributor list.
|
||||
|
||||
### Patch requirements
|
||||
|
||||
@@ -116,27 +116,27 @@ C4 is meant to provide a reusable optimal collaboration model for open source so
|
||||
- A patch SHOULD be a minimal and accurate answer to exactly one identified and agreed problem.
|
||||
- A patch MUST adhere to the code style guidelines of the project if these are defined.
|
||||
- A patch MUST adhere to the "Evolution of Public Contracts" guidelines defined below.
|
||||
- A patch MUST NOT include non-trivial code from other projects unless the Contributor is the original author of that code.
|
||||
- A patch SHALL NOT include non-trivial code from other projects unless the Contributor is the original author of that code.
|
||||
- A patch MUST compile cleanly and pass project self-tests on at least the principle target platform.
|
||||
- A patch commit message SHOULD consist of a single short (less than 50 character) line summarizing the change, optionally followed by a blank line and then a more thorough description.
|
||||
- A "Correct Patch" is one that satisfies the above requirements.
|
||||
|
||||
### Development process
|
||||
|
||||
- Change on the project MUST be governed by the pattern of accurately identifying problems and applying minimal, accurate solutions to these problems.
|
||||
- Change on the project SHALL be governed by the pattern of accurately identifying problems and applying minimal, accurate solutions to these problems.
|
||||
- To request changes, a user SHOULD log an issue on the project Platform issue tracker.
|
||||
- The user or Contributor SHOULD write the issue by describing the problem they face or observe.
|
||||
- The user or Contributor SHOULD seek consensus on the accuracy of their observation, and the value of solving the problem.
|
||||
- Users MUST NOT log feature requests, ideas, or suggestions unrelated to Monero code or Monero's dependency code or Monero's potential/future dependency code or research which successfully implements Monero.
|
||||
- Users MUST NOT log any solutions to problems (verifiable or hypothetical) of which are not explicitly documented and/or not provable and/or cannot be reasonably proven.
|
||||
- Thus, the release history of the project MUST be a list of meaningful issues logged and solved.
|
||||
- To work on an issue, a Contributor MUST fork the project repository and then work on their forked repository.
|
||||
- To submit a patch, a Contributor MUST create a Platform pull request back to the project.
|
||||
- A Contributor MUST NOT commit changes directly to the project.
|
||||
- Users SHALL NOT log feature requests, ideas, or suggestions unrelated to Monero code or Monero's dependency code or Monero's potential/future dependency code or research which successfully implements Monero.
|
||||
- Users SHALL NOT log any solutions to problems (verifiable or hypothetical) of which are not explicitly documented and/or not provable and/or cannot be reasonably proven.
|
||||
- Thus, the release history of the project SHALL be a list of meaningful issues logged and solved.
|
||||
- To work on an issue, a Contributor SHALL fork the project repository and then work on their forked repository.
|
||||
- To submit a patch, a Contributor SHALL create a Platform pull request back to the project.
|
||||
- A Contributor SHALL NOT commit changes directly to the project.
|
||||
- To discuss a patch, people MAY comment on the Platform pull request, on the commit, or elsewhere.
|
||||
- To accept or reject a patch, a Maintainer MUST use the Platform interface.
|
||||
- To accept or reject a patch, a Maintainer SHALL use the Platform interface.
|
||||
- Maintainers SHOULD NOT merge their own patches except in exceptional cases, such as non-responsiveness from other Maintainers for an extended period (more than 30 days) or unless urgent as defined by the Monero Maintainers Team.
|
||||
- Maintainers MUST NOT make value judgments on correct patches unless the Maintainer (as may happen in rare circumstances) is a core code developer.
|
||||
- Maintainers SHALL NOT make value judgments on correct patches unless the Maintainer (as may happen in rare circumstances) is a core code developer.
|
||||
- Maintainers MUST NOT merge pull requests in less than 168 hours (1 week) unless deemed urgent by at least 2 people from the Monero Maintainer Team.
|
||||
- The Contributor MAY tag an issue as "Ready" after making a pull request for the issue.
|
||||
- The user who created an issue SHOULD close the issue after checking the patch is successful.
|
||||
@@ -146,27 +146,27 @@ C4 is meant to provide a reusable optimal collaboration model for open source so
|
||||
|
||||
### Creating stable releases
|
||||
|
||||
- The project MUST have one branch ("master") that always holds the latest in-progress version and SHOULD always build.
|
||||
- The project MUST NOT use topic branches for any reason. Personal forks MAY use topic branches.
|
||||
- To make a stable release someone MUST fork the repository by copying it and thus become maintainer of this repository.
|
||||
- The project SHALL have one branch ("master") that always holds the latest in-progress version and SHOULD always build.
|
||||
- The project SHALL NOT use topic branches for any reason. Personal forks MAY use topic branches.
|
||||
- To make a stable release someone SHALL fork the repository by copying it and thus become maintainer of this repository.
|
||||
- Forking a project for stabilization MAY be done unilaterally and without agreement of project maintainers.
|
||||
- A patch to a stabilization project declared "stable" MUST be accompanied by a reproducible test case.
|
||||
- A patch to a stabilization project declared "stable" SHALL be accompanied by a reproducible test case.
|
||||
|
||||
### Evolution of public contracts
|
||||
|
||||
- All Public Contracts (APIs or protocols) MUST be documented.
|
||||
- All Public Contracts (APIs or protocols) SHALL be documented.
|
||||
- All Public Contracts SHOULD have space for extensibility and experimentation.
|
||||
- A patch that modifies a stable Public Contract SHOULD not break existing applications unless there is overriding consensus on the value of doing this.
|
||||
- A patch that introduces new features to a Public Contract SHOULD do so using new names.
|
||||
- Old names SHOULD be deprecated in a systematic fashion by marking new names as "experimental" until they are stable, then marking the old names as "deprecated".
|
||||
- When sufficient time has passed, old deprecated names SHOULD be marked "legacy" and eventually removed.
|
||||
- Old names MUST NOT be reused by new features.
|
||||
- Old names SHALL NOT be reused by new features.
|
||||
- When old names are removed, their implementations MUST provoke an exception (assertion) if used by applications.
|
||||
|
||||
### Project administration
|
||||
|
||||
- The project founders MUST act as Administrators to manage the set of project Maintainers.
|
||||
- The Administrators MUST ensure their own succession over time by promoting the most effective Maintainers.
|
||||
- A new Contributor who makes a correct patch MUST be invited to become a Maintainer.
|
||||
- The project founders SHALL act as Administrators to manage the set of project Maintainers.
|
||||
- The Administrators SHALL ensure their own succession over time by promoting the most effective Maintainers.
|
||||
- A new Contributor who makes a correct patch SHALL be invited to become a Maintainer.
|
||||
- Administrators MAY remove Maintainers who are inactive for an extended period of time, or who repeatedly fail to apply this process accurately.
|
||||
- Administrators SHOULD block or ban "bad actors" who cause stress and pain to others in the project. This should be done after public discussion, with a chance for all parties to speak. A bad actor is someone who repeatedly ignores the rules and culture of the project, who is needlessly argumentative or hostile, or who is offensive, and who is unable to self-correct their behavior when asked to do so by others.
|
||||
|
||||
68
Dockerfile
68
Dockerfile
@@ -25,13 +25,10 @@ RUN set -ex && \
|
||||
|
||||
WORKDIR /usr/local
|
||||
|
||||
ENV CFLAGS='-fPIC'
|
||||
ENV CXXFLAGS='-fPIC'
|
||||
|
||||
#Cmake
|
||||
ARG CMAKE_VERSION=3.14.0
|
||||
ARG CMAKE_VERSION_DOT=v3.14
|
||||
ARG CMAKE_HASH=aa76ba67b3c2af1946701f847073f4652af5cbd9f141f221c97af99127e75502
|
||||
ARG CMAKE_VERSION=3.13.0
|
||||
ARG CMAKE_VERSION_DOT=v3.13
|
||||
ARG CMAKE_HASH=4058b2f1a53c026564e8936698d56c3b352d90df067b195cb749a97a3d273c90
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://cmake.org/files/${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION}.tar.gz \
|
||||
&& echo "${CMAKE_HASH} cmake-${CMAKE_VERSION}.tar.gz" | sha256sum -c \
|
||||
@@ -42,41 +39,41 @@ RUN set -ex \
|
||||
&& make install
|
||||
|
||||
## Boost
|
||||
ARG BOOST_VERSION=1_69_0
|
||||
ARG BOOST_VERSION_DOT=1.69.0
|
||||
ARG BOOST_HASH=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406
|
||||
ARG BOOST_VERSION=1_68_0
|
||||
ARG BOOST_VERSION_DOT=1.68.0
|
||||
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& cd boost_${BOOST_VERSION} \
|
||||
&& ./bootstrap.sh \
|
||||
&& ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="$CFLAGS" cxxflags="$CXXFLAGS" stage
|
||||
&& ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale threading=multi threadapi=pthread cflags="-fPIC" cxxflags="-fPIC" stage
|
||||
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
|
||||
|
||||
# OpenSSL
|
||||
ARG OPENSSL_VERSION=1.1.1b
|
||||
ARG OPENSSL_HASH=5c557b023230413dfb0756f3137a13e6d726838ccd1430888ad15bfb2b43ea4b
|
||||
ARG OPENSSL_VERSION=1.1.0j
|
||||
ARG OPENSSL_HASH=31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \
|
||||
&& cd openssl-${OPENSSL_VERSION} \
|
||||
&& ./Configure linux-x86_64 no-shared --static "$CFLAGS" \
|
||||
&& ./Configure linux-x86_64 no-shared --static -fPIC \
|
||||
&& make build_generated \
|
||||
&& make libcrypto.a \
|
||||
&& make install
|
||||
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
|
||||
|
||||
# ZMQ
|
||||
ARG ZMQ_VERSION=v4.3.1
|
||||
ARG ZMQ_HASH=2cb1240db64ce1ea299e00474c646a2453a8435b
|
||||
ARG ZMQ_VERSION=v4.2.5
|
||||
ARG ZMQ_HASH=d062edd8c142384792955796329baf1e5a3377cd
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \
|
||||
&& cd libzmq \
|
||||
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
@@ -91,39 +88,39 @@ RUN set -ex \
|
||||
&& mv *.hpp /usr/local/include
|
||||
|
||||
# Readline
|
||||
ARG READLINE_VERSION=8.0
|
||||
ARG READLINE_HASH=e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461
|
||||
ARG READLINE_VERSION=7.0
|
||||
ARG READLINE_HASH=750d437185286f40a369e1e4f4764eda932b9459b5ec9a731628393dd3d32334
|
||||
RUN set -ex \
|
||||
&& curl -s -O https://ftp.gnu.org/gnu/readline/readline-${READLINE_VERSION}.tar.gz \
|
||||
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" | sha256sum -c \
|
||||
&& tar -xzf readline-${READLINE_VERSION}.tar.gz \
|
||||
&& cd readline-${READLINE_VERSION} \
|
||||
&& ./configure \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Sodium
|
||||
ARG SODIUM_VERSION=1.0.17
|
||||
ARG SODIUM_HASH=b732443c442239c2e0184820e9b23cca0de0828c
|
||||
ARG SODIUM_VERSION=1.0.16
|
||||
ARG SODIUM_HASH=675149b9b8b66ff44152553fb3ebf9858128363d
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \
|
||||
&& cd libsodium \
|
||||
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure \
|
||||
&& make \
|
||||
&& make check \
|
||||
&& make install
|
||||
|
||||
# Udev
|
||||
ARG UDEV_VERSION=v3.2.7
|
||||
ARG UDEV_HASH=4758e346a14126fc3a964de5831e411c27ebe487
|
||||
ARG UDEV_VERSION=v3.2.6
|
||||
ARG UDEV_HASH=0c35b136c08d64064efa55087c54364608e65ed6
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/gentoo/eudev -b ${UDEV_VERSION} \
|
||||
&& cd eudev \
|
||||
&& test `git rev-parse HEAD` = ${UDEV_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --disable-gudev --disable-introspection --disable-hwdb --disable-manpages --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
@@ -135,7 +132,7 @@ RUN set -ex \
|
||||
&& cd libusb \
|
||||
&& test `git rev-parse HEAD` = ${USB_HASH} || exit 1 \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --disable-shared \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
@@ -147,20 +144,20 @@ RUN set -ex \
|
||||
&& cd hidapi \
|
||||
&& test `git rev-parse HEAD` = ${HIDAPI_HASH} || exit 1 \
|
||||
&& ./bootstrap \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
# Protobuf
|
||||
ARG PROTOBUF_VERSION=v3.7.0
|
||||
ARG PROTOBUF_HASH=582743bf40c5d3639a70f98f183914a2c0cd0680
|
||||
ARG PROTOBUF_VERSION=v3.6.1
|
||||
ARG PROTOBUF_HASH=48cb18e5c419ddd23d9badcfe4e9df7bde1979b2
|
||||
RUN set -ex \
|
||||
&& git clone https://github.com/protocolbuffers/protobuf -b ${PROTOBUF_VERSION} \
|
||||
&& cd protobuf \
|
||||
&& test `git rev-parse HEAD` = ${PROTOBUF_HASH} || exit 1 \
|
||||
&& git submodule update --init --recursive \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-static --disable-shared \
|
||||
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --enable-static --disable-shared \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& ldconfig
|
||||
@@ -188,14 +185,8 @@ RUN set -ex && \
|
||||
rm -rf /var/lib/apt
|
||||
COPY --from=builder /src/build/release/bin /usr/local/bin/
|
||||
|
||||
# Create monero user
|
||||
RUN adduser --system --group --disabled-password monero && \
|
||||
mkdir -p /wallet /home/monero/.bitmonero && \
|
||||
chown -R monero:monero /home/monero/.bitmonero && \
|
||||
chown -R monero:monero /wallet
|
||||
|
||||
# Contains the blockchain
|
||||
VOLUME /home/monero/.bitmonero
|
||||
VOLUME /root/.bitmonero
|
||||
|
||||
# Generate your wallet via accessing the container and run:
|
||||
# cd /wallet
|
||||
@@ -205,8 +196,5 @@ VOLUME /wallet
|
||||
EXPOSE 18080
|
||||
EXPOSE 18081
|
||||
|
||||
# switch to user monero
|
||||
USER monero
|
||||
|
||||
ENTRYPOINT ["monerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--confirm-external-bind"]
|
||||
|
||||
|
||||
10
LICENSE
10
LICENSE
@@ -29,13 +29,3 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Parts of the project are originally copyright (c) 2012-2013 The Cryptonote
|
||||
developers
|
||||
|
||||
Parts of the project are originally copyright (c) 2014 The Boolberry
|
||||
developers, distributed under the MIT licence:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
4
Makefile
4
Makefile
@@ -63,10 +63,6 @@ debug-test:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE) && $(MAKE) ARGS="-E libwallet_api_tests" test
|
||||
|
||||
debug-test-trezor:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -D BUILD_TESTS=ON -D TREZOR_DEBUG=ON -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE) && $(MAKE) ARGS="-E libwallet_api_tests" test
|
||||
|
||||
debug-all:
|
||||
mkdir -p $(builddir)/debug
|
||||
cd $(builddir)/debug && cmake -D BUILD_TESTS=OFF -D BUILD_SHARED_LIBS=OFF -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE)
|
||||
|
||||
6
PKGBUILD
6
PKGBUILD
@@ -3,7 +3,8 @@
|
||||
|
||||
pkgbase=('wownero-git')
|
||||
pkgname=('wownero-git')
|
||||
pkgver=0.5.0.2
|
||||
_gitbranch='dev-v0.5'
|
||||
pkgver=0.5.0.0
|
||||
pkgrel=1
|
||||
pkgdesc="a fairly launched privacy-centric meme coin with no premine and a finite supply"
|
||||
license=('custom:Cryptonote')
|
||||
@@ -13,7 +14,7 @@ depends=('boost-libs' 'zeromq' 'unbound' 'libusb')
|
||||
makedepends=('git' 'cmake' 'boost')
|
||||
provides=('wownero-git')
|
||||
|
||||
source=("${pkgname}"::"git+https://github.com/wownero/wownero")
|
||||
source=("${pkgname}"::"git+https://github.com/wownero/wownero#branch=${_gitbranch}")
|
||||
|
||||
sha256sums=('SKIP')
|
||||
|
||||
@@ -25,7 +26,6 @@ pkgver() {
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname}"
|
||||
git fetch --tags && git checkout tags/v0.5.0.2 -b v0.5.0.2
|
||||
USE_SINGLE_BUILDDIR=1 make
|
||||
}
|
||||
|
||||
|
||||
@@ -15,33 +15,23 @@ You do not need anything from Qt in order to use the final translations.
|
||||
|
||||
To update ts files after changing source code:
|
||||
|
||||
```bash
|
||||
./utils/translations/update-translations.sh
|
||||
```
|
||||
./utils/translations/update-translations.sh
|
||||
|
||||
To add a new language, eg Spanish (ISO code es):
|
||||
|
||||
```bash
|
||||
cp translations/monero.ts translations/monero_es.ts
|
||||
```
|
||||
cp translations/monero.ts translations/monero_es.ts
|
||||
|
||||
To edit translations for Spanish:
|
||||
|
||||
```bash
|
||||
linguist translations/monero_es.ts
|
||||
```
|
||||
linguist translations/monero_es.ts
|
||||
|
||||
To build translations after modifying them:
|
||||
|
||||
```bash
|
||||
./utils/translations/build-translations.sh
|
||||
```
|
||||
./utils/translations/build-translations.sh
|
||||
|
||||
To test a translation:
|
||||
|
||||
```bash
|
||||
LANG=es ./build/release/bin/monero-wallet-cli
|
||||
```
|
||||
LANG=es ./build/release/bin/monero-wallet-cli
|
||||
|
||||
To add new translatable strings in the source code:
|
||||
|
||||
@@ -49,8 +39,6 @@ Use the `tr(string)` function if possible. If the code is in a class, and this c
|
||||
|
||||
If you're getting messages of the form:
|
||||
|
||||
```
|
||||
Class 'cryptonote::simple_wallet' lacks Q_OBJECT macro
|
||||
```
|
||||
Class 'cryptonote::simple_wallet' lacks Q_OBJECT macro
|
||||
|
||||
all is fine, we don't actually need that here.
|
||||
|
||||
11
README.md
11
README.md
@@ -1,6 +1,6 @@
|
||||
# ~~Mo~~Wownero - Such privacy! Many coins! Wow! 🐕
|
||||
|
||||
Copyright (c) 2014-2019 The Monero Project.
|
||||
Copyright (c) 2014-2018 The Monero Project.
|
||||
Portions Copyright (c) 2012-2013 The Cryptonote developers.
|
||||
|
||||
## Resources
|
||||
@@ -33,14 +33,15 @@ Wownero is a privacy-centric memecoin that was fairly launched on April 1, 2018
|
||||
Wownero uses a fixed-schedule software upgrade (hard fork) mechanism to implement new features. This means that users of Wownero (end users and service providers) should run current versions and upgrade their software on a regular schedule. The required software for these upgrades will be available prior to the scheduled date. Please check the repository prior to this date for the proper Wownero software version. Below is the historical schedule and the projected schedule for the next upgrade.
|
||||
Dates are provided in the format YYYY-MM-DD.
|
||||
|
||||
|
||||
|
||||
| Software upgrade block height | Date | Release Name | Minimum Wownero version | Recommended Wownero version | Details |
|
||||
| ------------------------------ | -----------| ----------------- | ---------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| 1 | 2018-04-01 | Awesome Akita | v0.1.0.0 | v0.1.0.0 | Cryptonight variant 1, ringsize >= 8, sorted inputs
|
||||
| 6969 | 2018-04-24 | Busty Brazzers | v0.2.0.0 | v0.2.0.0 | Bulletproofs, LWMA difficulty algorithm, ringsize >= 10, reduce unlock to 4
|
||||
| 53666 | 2018-10-06 | Cool Cage | v0.3.0.0 | v0.3.1.3 | Cryptonight variant 2, LWMA v2, ringsize = 22, MMS
|
||||
| 63469 | 2018-11-11 | Dank Doge | v0.4.0.0 | v0.4.0.0 | LWMA v4
|
||||
| 81769 | 2019-02-19 | Erotic EggplantEmoji | v0.5.0.0 | v0.5.0.2 | Cryptonight/wow, LWMA v1 with N=144, Updated Bulletproofs, Fee Per Byte, Auto-churn
|
||||
| 114969 | 2019-06-14 | F For Fappening | v0.6.0.0 | v0.6.0.0 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 81769 | 2019-02-14 | Erotic EggplantEmoji | v0.5.0.0 | v0.5.0.0 | Cryptonight/wow, LWMA v1 with N=144, Updated Bulletproofs, Fee Per Byte, Auto-churn
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
@@ -64,8 +65,8 @@ Packages are available for
|
||||
|
||||
* Ubuntu 18.04/Ubuntu 16.04/Debian 9/Debian 8 (amd64)
|
||||
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B09DF0E4B0C56A94
|
||||
sudo add-apt-repository "deb http://ppa.wownero.com/ bionic main"
|
||||
add-apt-repository "deb http://ppa.wownero.com/ bionic main"
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B09DF0E4B0C56A94
|
||||
sudo apt-get update
|
||||
sudo apt-get install wownero
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
OPTION(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
||||
OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" ON)
|
||||
OPTION(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
|
||||
OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" OFF)
|
||||
OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" OFF)
|
||||
OPTION(USE_DEVICE_TREZOR_DEBUG "Trezor Debugging enabled" OFF)
|
||||
OPTION(TREZOR_DEBUG "Main trezor debugging switch" OFF)
|
||||
|
||||
# Helper function to fix cmake < 3.6.0 FindProtobuf variables
|
||||
function(_trezor_protobuf_fix_vars)
|
||||
@@ -55,14 +53,6 @@ if (USE_DEVICE_TREZOR)
|
||||
set(Protobuf_FOUND 1) # override found if all rquired info was provided by variables
|
||||
endif()
|
||||
|
||||
if(TREZOR_DEBUG)
|
||||
set(USE_DEVICE_TREZOR_DEBUG 1)
|
||||
endif()
|
||||
|
||||
# Compile debugging support (for tests)
|
||||
if (USE_DEVICE_TREZOR_DEBUG)
|
||||
add_definitions(-DWITH_TREZOR_DEBUGGING=1)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Trezor support disabled by USE_DEVICE_TREZOR")
|
||||
endif()
|
||||
@@ -116,12 +106,7 @@ endif()
|
||||
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_TEST_PASSED)
|
||||
set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}")
|
||||
set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
set(TREZOR_PROTOBUF_PARAMS "")
|
||||
if (USE_DEVICE_TREZOR_DEBUG)
|
||||
set(TREZOR_PROTOBUF_PARAMS "--debug")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
|
||||
if(RET)
|
||||
message(WARNING "Trezor protobuf messages could not be regenerated (err=${RET}, python ${PYTHON})."
|
||||
"OUT: ${OUT}, ERR: ${ERR}."
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# FindBacktrace
|
||||
# -------------
|
||||
#
|
||||
# Find provider for backtrace(3).
|
||||
#
|
||||
# Checks if OS supports backtrace(3) via either libc or custom library.
|
||||
# This module defines the following variables:
|
||||
#
|
||||
# ``Backtrace_HEADER``
|
||||
# The header file needed for backtrace(3). Cached.
|
||||
# Could be forcibly set by user.
|
||||
# ``Backtrace_INCLUDE_DIRS``
|
||||
# The include directories needed to use backtrace(3) header.
|
||||
# ``Backtrace_LIBRARIES``
|
||||
# The libraries (linker flags) needed to use backtrace(3), if any.
|
||||
# ``Backtrace_FOUND``
|
||||
# Is set if and only if backtrace(3) support detected.
|
||||
#
|
||||
# The following cache variables are also available to set or use:
|
||||
#
|
||||
# ``Backtrace_LIBRARY``
|
||||
# The external library providing backtrace, if any.
|
||||
# ``Backtrace_INCLUDE_DIR``
|
||||
# The directory holding the backtrace(3) header.
|
||||
#
|
||||
# Typical usage is to generate of header file using configure_file() with the
|
||||
# contents like the following::
|
||||
#
|
||||
# #cmakedefine01 Backtrace_FOUND
|
||||
# #if Backtrace_FOUND
|
||||
# # include <${Backtrace_HEADER}>
|
||||
# #endif
|
||||
#
|
||||
# And then reference that generated header file in actual source.
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
# List of variables to be provided to find_package_handle_standard_args()
|
||||
set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
|
||||
|
||||
if(Backtrace_HEADER)
|
||||
set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
|
||||
else(Backtrace_HEADER)
|
||||
set(_Backtrace_HEADER_TRY "execinfo.h")
|
||||
endif(Backtrace_HEADER)
|
||||
|
||||
find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
|
||||
set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
|
||||
if (NOT DEFINED Backtrace_LIBRARY)
|
||||
# First, check if we already have backtrace(), e.g., in libc
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_QUIET ${Backtrace_FIND_QUIETLY})
|
||||
check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
if(_Backtrace_SYM_FOUND)
|
||||
# Avoid repeating the message() call below each time CMake is run.
|
||||
if(NOT Backtrace_FIND_QUIETLY AND NOT DEFINED Backtrace_LIBRARY)
|
||||
message(STATUS "backtrace facility detected in default set of libraries")
|
||||
endif()
|
||||
set(Backtrace_LIBRARY "" CACHE FILEPATH "Library providing backtrace(3), empty for default set of libraries")
|
||||
else()
|
||||
# Check for external library, for non-glibc systems
|
||||
if(Backtrace_INCLUDE_DIR)
|
||||
# OpenBSD has libbacktrace renamed to libexecinfo
|
||||
find_library(Backtrace_LIBRARY "execinfo")
|
||||
elseif() # respect user wishes
|
||||
set(_Backtrace_HEADER_TRY "backtrace.h")
|
||||
find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
|
||||
find_library(Backtrace_LIBRARY "backtrace")
|
||||
endif()
|
||||
|
||||
# Prepend list with library path as it's more common practice
|
||||
set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
|
||||
endif()
|
||||
|
||||
message(STATUS "Backtrace_LIBRARY: ${Backtrace_LIBRARY}")
|
||||
if(Backtrace_LIBRARY STREQUAL "NOTFOUND")
|
||||
set(Backtrace_LIBRARY "")
|
||||
endif()
|
||||
if(Backtrace_LIBRARY STREQUAL "Backtrace_LIBRARY-NOTFOUND")
|
||||
set(Backtrace_LIBRARY "")
|
||||
endif()
|
||||
|
||||
set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
|
||||
set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
|
||||
|
||||
find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
|
||||
mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)
|
||||
@@ -99,18 +99,9 @@ if ( LibUSB_FOUND )
|
||||
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 )
|
||||
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 )
|
||||
|
||||
if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||
find_library(LIBUDEV_LIBRARY udev)
|
||||
if(LIBUDEV_LIBRARY)
|
||||
set(LibUSB_LIBRARIES "${LibUSB_LIBRARIES};${LIBUDEV_LIBRARY}")
|
||||
else()
|
||||
message(WARNING "libudev library not found, binaries may fail to link.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Library 1.0.16+ compilation test.
|
||||
# The check_library_exists does not work well on Apple with shared libs.
|
||||
if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC)
|
||||
if (APPLE OR LibUSB_VERSION_1.0.16)
|
||||
if (APPLE)
|
||||
if(DEPENDS)
|
||||
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# Brewfile for Monero
|
||||
# A homebrew Brewfile installs all required dependencies in one shot
|
||||
# see https://coderwall.com/p/afmnbq/homebrew-s-new-feature-brewfiles
|
||||
# https://github.com/Homebrew/homebrew-bundle
|
||||
# execute brew bundle in the directory containing the Brewfile
|
||||
|
||||
tap "homebrew/bundle"
|
||||
tap "homebrew/cask"
|
||||
tap "homebrew/cask-versions"
|
||||
tap "homebrew/core"
|
||||
|
||||
brew "autoconf"
|
||||
brew "autogen"
|
||||
brew "automake"
|
||||
brew "binutils"
|
||||
brew "coreutils"
|
||||
brew "cmake"
|
||||
brew "pkg-config"
|
||||
brew "boost"
|
||||
brew "openssl"
|
||||
brew "hidapi"
|
||||
brew "zmq"
|
||||
brew "libpgm"
|
||||
brew "unbound"
|
||||
brew "libsodium"
|
||||
brew "miniupnpc"
|
||||
brew "readline"
|
||||
brew "ldns"
|
||||
brew "expat"
|
||||
brew "doxygen"
|
||||
brew "graphviz"
|
||||
brew "libunwind-headers"
|
||||
brew "xz"
|
||||
brew "protobuf"
|
||||
@@ -22,16 +22,9 @@ host_toolchain:=$(HOST)-
|
||||
endif
|
||||
|
||||
ifneq ($(DEBUG),)
|
||||
release_type=Debug
|
||||
release_type=debug
|
||||
else
|
||||
release_type=Release
|
||||
endif
|
||||
|
||||
ifneq ($(TESTS),)
|
||||
build_tests=ON
|
||||
release_type=Debug
|
||||
else
|
||||
build_tests=OFF
|
||||
release_type=release
|
||||
endif
|
||||
|
||||
base_build_dir=$(BASEDIR)/work/build
|
||||
@@ -101,8 +94,8 @@ $(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null)
|
||||
$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null)
|
||||
$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null)
|
||||
|
||||
qt_packages_$(NO_QT) = $(qt_packages)
|
||||
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_)
|
||||
|
||||
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages)
|
||||
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
|
||||
|
||||
all_packages = $(packages) $(native_packages)
|
||||
@@ -171,8 +164,6 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_
|
||||
-e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
|
||||
-e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \
|
||||
-e 's|@debug@|$(DEBUG)|' \
|
||||
-e 's|@release_type@|$(release_type)|' \
|
||||
-e 's|@build_tests@|$(build_tests)|' \
|
||||
-e 's|@depends@|$(host_cmake)|' \
|
||||
-e 's|@prefix@|$($(host_arch)_$(host_os)_prefix)|'\
|
||||
-e 's|@sdk@|$(SDK_PATH)|'\
|
||||
|
||||
@@ -2,29 +2,21 @@
|
||||
|
||||
To build dependencies for the current arch+OS:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
make
|
||||
|
||||
To build for another arch/OS:
|
||||
|
||||
```bash
|
||||
make HOST=host-platform-triplet
|
||||
```
|
||||
make HOST=host-platform-triplet
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
make HOST=x86_64-w64-mingw32 -j4
|
||||
```
|
||||
make HOST=x86_64-w64-mingw32 -j4
|
||||
|
||||
A toolchain will be generated that's suitable for plugging into Monero's
|
||||
cmake. In the above example, a dir named x86_64-w64-mingw32 will be
|
||||
created. To use it for Monero:
|
||||
|
||||
```bash
|
||||
cmake -DCMAKE_TOOLCHAIN=`pwd`/contrib/depends/x86_64-w64-mingw32
|
||||
```
|
||||
cmake -DCMAKE_TOOLCHAIN=`pwd`/contrib/depends/x86_64-w64-mingw32
|
||||
|
||||
Common `host-platform-triplets` for cross compilation are:
|
||||
|
||||
@@ -39,24 +31,20 @@ No other options are needed, the paths are automatically configured.
|
||||
Dependency Options:
|
||||
The following can be set when running make: make FOO=bar
|
||||
|
||||
```
|
||||
SOURCES_PATH: downloaded sources will be placed here
|
||||
BASE_CACHE: built packages will be placed here
|
||||
SDK_PATH: Path where sdk's can be found (used by OSX)
|
||||
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
|
||||
DEBUG: disable some optimizations and enable more runtime checking
|
||||
HOST_ID_SALT: Optional salt to use when generating host package ids
|
||||
BUILD_ID_SALT: Optional salt to use when generating build package ids
|
||||
```
|
||||
SOURCES_PATH: downloaded sources will be placed here
|
||||
BASE_CACHE: built packages will be placed here
|
||||
SDK_PATH: Path where sdk's can be found (used by OSX)
|
||||
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
|
||||
DEBUG: disable some optimizations and enable more runtime checking
|
||||
HOST_ID_SALT: Optional salt to use when generating host package ids
|
||||
BUILD_ID_SALT: Optional salt to use when generating build package ids
|
||||
|
||||
Additional targets:
|
||||
|
||||
```
|
||||
download: run 'make download' to fetch all sources without building them
|
||||
download-osx: run 'make download-osx' to fetch all sources needed for osx builds
|
||||
download-win: run 'make download-win' to fetch all sources needed for win builds
|
||||
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
|
||||
```
|
||||
download: run 'make download' to fetch all sources without building them
|
||||
download-osx: run 'make download-osx' to fetch all sources needed for osx builds
|
||||
download-win: run 'make download-win' to fetch all sources needed for win builds
|
||||
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
|
||||
|
||||
#Darwin (macos) builds:
|
||||
|
||||
|
||||
@@ -9,43 +9,39 @@ General tips:
|
||||
## Identifiers
|
||||
Each package is required to define at least these variables:
|
||||
|
||||
```
|
||||
$(package)_version:
|
||||
Version of the upstream library or program. If there is no version, a
|
||||
placeholder such as 1.0 can be used.
|
||||
$(package)_version:
|
||||
Version of the upstream library or program. If there is no version, a
|
||||
placeholder such as 1.0 can be used.
|
||||
|
||||
$(package)_download_path:
|
||||
Location of the upstream source, without the file-name. Usually http or
|
||||
ftp.
|
||||
$(package)_download_path:
|
||||
Location of the upstream source, without the file-name. Usually http or
|
||||
ftp.
|
||||
|
||||
$(package)_file_name:
|
||||
The upstream source filename available at the download path.
|
||||
$(package)_file_name:
|
||||
The upstream source filename available at the download path.
|
||||
|
||||
$(package)_sha256_hash:
|
||||
The sha256 hash of the upstream file
|
||||
```
|
||||
$(package)_sha256_hash:
|
||||
The sha256 hash of the upstream file
|
||||
|
||||
These variables are optional:
|
||||
|
||||
```
|
||||
$(package)_build_subdir:
|
||||
cd to this dir before running configure/build/stage commands.
|
||||
$(package)_build_subdir:
|
||||
cd to this dir before running configure/build/stage commands.
|
||||
|
||||
$(package)_download_file:
|
||||
The file-name of the upstream source if it differs from how it should be
|
||||
stored locally. This can be used to avoid storing file-names with strange
|
||||
characters.
|
||||
|
||||
$(package)_dependencies:
|
||||
Names of any other packages that this one depends on.
|
||||
|
||||
$(package)_patches:
|
||||
Filenames of any patches needed to build the package
|
||||
|
||||
$(package)_download_file:
|
||||
The file-name of the upstream source if it differs from how it should be
|
||||
stored locally. This can be used to avoid storing file-names with strange
|
||||
characters.
|
||||
|
||||
$(package)_dependencies:
|
||||
Names of any other packages that this one depends on.
|
||||
|
||||
$(package)_patches:
|
||||
Filenames of any patches needed to build the package
|
||||
|
||||
$(package)_extra_sources:
|
||||
Any extra files that will be fetched via $(package)_fetch_cmds. These are
|
||||
specified so that they can be fetched and verified via 'make download'.
|
||||
```
|
||||
$(package)_extra_sources:
|
||||
Any extra files that will be fetched via $(package)_fetch_cmds. These are
|
||||
specified so that they can be fetched and verified via 'make download'.
|
||||
|
||||
|
||||
## Build Variables:
|
||||
@@ -53,55 +49,47 @@ After defining the main identifiers, build variables may be added or customized
|
||||
before running the build commands. They should be added to a function called
|
||||
$(package)_set_vars. For example:
|
||||
|
||||
```
|
||||
define $(package)_set_vars
|
||||
...
|
||||
endef
|
||||
```
|
||||
define $(package)_set_vars
|
||||
...
|
||||
endef
|
||||
|
||||
Most variables can be prefixed with the host, architecture, or both, to make
|
||||
the modifications specific to that case. For example:
|
||||
|
||||
```
|
||||
Universal: $(package)_cc=gcc
|
||||
Linux only: $(package)_linux_cc=gcc
|
||||
x86_64 only: $(package)_x86_64_cc = gcc
|
||||
x86_64 linux only: $(package)_x86_64_linux_cc = gcc
|
||||
```
|
||||
Universal: $(package)_cc=gcc
|
||||
Linux only: $(package)_linux_cc=gcc
|
||||
x86_64 only: $(package)_x86_64_cc = gcc
|
||||
x86_64 linux only: $(package)_x86_64_linux_cc = gcc
|
||||
|
||||
These variables may be set to override or append their default values.
|
||||
|
||||
```
|
||||
$(package)_cc
|
||||
$(package)_cxx
|
||||
$(package)_objc
|
||||
$(package)_objcxx
|
||||
$(package)_ar
|
||||
$(package)_ranlib
|
||||
$(package)_libtool
|
||||
$(package)_nm
|
||||
$(package)_cflags
|
||||
$(package)_cxxflags
|
||||
$(package)_ldflags
|
||||
$(package)_cppflags
|
||||
$(package)_config_env
|
||||
$(package)_build_env
|
||||
$(package)_stage_env
|
||||
$(package)_build_opts
|
||||
$(package)_config_opts
|
||||
```
|
||||
$(package)_cc
|
||||
$(package)_cxx
|
||||
$(package)_objc
|
||||
$(package)_objcxx
|
||||
$(package)_ar
|
||||
$(package)_ranlib
|
||||
$(package)_libtool
|
||||
$(package)_nm
|
||||
$(package)_cflags
|
||||
$(package)_cxxflags
|
||||
$(package)_ldflags
|
||||
$(package)_cppflags
|
||||
$(package)_config_env
|
||||
$(package)_build_env
|
||||
$(package)_stage_env
|
||||
$(package)_build_opts
|
||||
$(package)_config_opts
|
||||
|
||||
The `*_env` variables are used to add environment variables to the respective
|
||||
The *_env variables are used to add environment variables to the respective
|
||||
commands.
|
||||
|
||||
Many variables respect a debug/release suffix as well, in order to use them for
|
||||
only the appropriate build config. For example:
|
||||
|
||||
```
|
||||
$(package)_cflags_release = -O3
|
||||
$(package)_cflags_i686_debug = -g
|
||||
$(package)_config_opts_release = --disable-debug
|
||||
```
|
||||
$(package)_cflags_release = -O3
|
||||
$(package)_cflags_i686_debug = -g
|
||||
$(package)_config_opts_release = --disable-debug
|
||||
|
||||
These will be used in addition to the options that do not specify
|
||||
debug/release. All builds are considered to be release unless DEBUG=1 is set by
|
||||
@@ -109,57 +97,51 @@ the user. Other variables may be defined as needed.
|
||||
|
||||
## Build commands:
|
||||
|
||||
For each build, a unique build dir and staging dir are created. For example,
|
||||
`work/build/mylib/1.0-1adac830f6e` and `work/staging/mylib/1.0-1adac830f6e`.
|
||||
For each build, a unique build dir and staging dir are created. For example,
|
||||
`work/build/mylib/1.0-1adac830f6e` and `work/staging/mylib/1.0-1adac830f6e`.
|
||||
|
||||
The following build commands are available for each recipe:
|
||||
The following build commands are available for each recipe:
|
||||
|
||||
```
|
||||
$(package)_fetch_cmds:
|
||||
Runs from: build dir
|
||||
Fetch the source file. If undefined, it will be fetched and verified
|
||||
against its hash.
|
||||
$(package)_fetch_cmds:
|
||||
Runs from: build dir
|
||||
Fetch the source file. If undefined, it will be fetched and verified
|
||||
against its hash.
|
||||
|
||||
$(package)_extract_cmds:
|
||||
Runs from: build dir
|
||||
Verify the source file against its hash and extract it. If undefined, the
|
||||
source is assumed to be a tarball.
|
||||
$(package)_extract_cmds:
|
||||
Runs from: build dir
|
||||
Verify the source file against its hash and extract it. If undefined, the
|
||||
source is assumed to be a tarball.
|
||||
|
||||
$(package)_preprocess_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Preprocess the source as necessary. If undefined, does nothing.
|
||||
$(package)_preprocess_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Preprocess the source as necessary. If undefined, does nothing.
|
||||
|
||||
$(package)_config_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Configure the source. If undefined, does nothing.
|
||||
$(package)_config_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Configure the source. If undefined, does nothing.
|
||||
|
||||
$(package)_build_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Build the source. If undefined, does nothing.
|
||||
$(package)_build_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Build the source. If undefined, does nothing.
|
||||
|
||||
$(package)_stage_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Stage the build results. If undefined, does nothing.
|
||||
```
|
||||
$(package)_stage_cmds:
|
||||
Runs from: build dir/$(package)_build_subdir
|
||||
Stage the build results. If undefined, does nothing.
|
||||
|
||||
The following variables are available for each recipe:
|
||||
|
||||
```
|
||||
$(1)_staging_dir: package's destination sysroot path
|
||||
$(1)_staging_prefix_dir: prefix path inside of the package's staging dir
|
||||
$(1)_extract_dir: path to the package's extracted sources
|
||||
$(1)_build_dir: path where configure/build/stage commands will be run
|
||||
$(1)_patch_dir: path where the package's patches (if any) are found
|
||||
```
|
||||
The following variables are available for each recipe:
|
||||
|
||||
$(1)_staging_dir: package's destination sysroot path
|
||||
$(1)_staging_prefix_dir: prefix path inside of the package's staging dir
|
||||
$(1)_extract_dir: path to the package's extracted sources
|
||||
$(1)_build_dir: path where configure/build/stage commands will be run
|
||||
$(1)_patch_dir: path where the package's patches (if any) are found
|
||||
|
||||
Notes on build commands:
|
||||
|
||||
For packages built with autotools, `$($(package)_autoconf)` can be used in the
|
||||
For packages built with autotools, $($(package)_autoconf) can be used in the
|
||||
configure step to (usually) correctly configure automatically. Any
|
||||
`$($(package)_config_opts`) will be appended.
|
||||
$($(package)_config_opts) will be appended.
|
||||
|
||||
Most autotools projects can be properly staged using:
|
||||
|
||||
```bash
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
```
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
|
||||
67
contrib/depends/packages/cmake/conf/mxe-conf.cmake.in
Normal file
67
contrib/depends/packages/cmake/conf/mxe-conf.cmake.in
Normal file
@@ -0,0 +1,67 @@
|
||||
# This file is part of MXE. See LICENSE.md for licensing information.
|
||||
|
||||
# https://cmake.org/cmake/help/latest
|
||||
|
||||
# Can't set `cmake_minimum_required` or `cmake_policy` in toolchain
|
||||
# since toolchain is read before CMakeLists.txt
|
||||
# See `target-cmake.in` for CMAKE_POLICY_DEFAULT_CMPNNNN
|
||||
|
||||
# Check if we are using mxe supplied version
|
||||
# - toolchain is included multiple times so set a guard in
|
||||
# environment to suppress duplicate messages
|
||||
if(NOT ${CMAKE_COMMAND} STREQUAL @PREFIX@/@BUILD@/bin/cmake AND NOT DEFINED ENV{_MXE_CMAKE_TOOLCHAIN_INCLUDED})
|
||||
message(WARNING "
|
||||
** Warning: direct use of toolchain file is deprecated
|
||||
** Please use prefixed wrapper script instead:
|
||||
@TARGET@-cmake [options] <path-to-source>
|
||||
- uses mxe supplied cmake version @CMAKE_VERSION@
|
||||
- loads toolchain
|
||||
- loads common run results
|
||||
- sets various policy defaults
|
||||
")
|
||||
set(ENV{_MXE_CMAKE_TOOLCHAIN_INCLUDED} TRUE)
|
||||
endif()
|
||||
|
||||
## General configuration
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(MSYS 1)
|
||||
set(CMAKE_EXPORT_NO_PACKAGE_REGISTRY ON)
|
||||
# Workaround for https://www.cmake.org/Bug/view.php?id=14075
|
||||
set(CMAKE_CROSS_COMPILING ON)
|
||||
|
||||
|
||||
## Library config
|
||||
set(BUILD_SHARED_LIBS @CMAKE_SHARED_BOOL@ CACHE BOOL "BUILD_SHARED_LIBS" FORCE)
|
||||
set(BUILD_STATIC_LIBS @CMAKE_STATIC_BOOL@ CACHE BOOL "BUILD_STATIC_LIBS" FORCE)
|
||||
set(BUILD_SHARED @CMAKE_SHARED_BOOL@ CACHE BOOL "BUILD_SHARED" FORCE)
|
||||
set(BUILD_STATIC @CMAKE_STATIC_BOOL@ CACHE BOOL "BUILD_STATIC" FORCE)
|
||||
set(LIBTYPE @LIBTYPE@)
|
||||
|
||||
|
||||
## Paths etc.
|
||||
set(CMAKE_FIND_ROOT_PATH @PREFIX@/@TARGET@)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_PREFIX_PATH @PREFIX@/@TARGET@)
|
||||
set(CMAKE_INSTALL_PREFIX @PREFIX@/@TARGET@ CACHE PATH "Installation Prefix")
|
||||
# For custom mxe FindPackage scripts
|
||||
set(CMAKE_MODULE_PATH "@PREFIX@/share/cmake/modules" ${CMAKE_MODULE_PATH})
|
||||
|
||||
|
||||
## Programs
|
||||
set(CMAKE_C_COMPILER @PREFIX@/bin/@TARGET@-gcc)
|
||||
set(CMAKE_CXX_COMPILER @PREFIX@/bin/@TARGET@-g++)
|
||||
set(CMAKE_Fortran_COMPILER @PREFIX@/bin/@TARGET@-gfortran)
|
||||
set(CMAKE_RC_COMPILER @PREFIX@/bin/@TARGET@-windres)
|
||||
# CMAKE_RC_COMPILE_OBJECT is defined in:
|
||||
# <cmake root>/share/cmake-X.Y/Modules/Platform/Windows-windres.cmake
|
||||
set(CPACK_NSIS_EXECUTABLE @TARGET@-makensis)
|
||||
|
||||
## Individual package configuration
|
||||
file(GLOB mxe_cmake_files
|
||||
"@CMAKE_TOOLCHAIN_DIR@/*.cmake"
|
||||
)
|
||||
foreach(mxe_cmake_file ${mxe_cmake_files})
|
||||
include(${mxe_cmake_file})
|
||||
endforeach()
|
||||
29
contrib/depends/packages/cmake/conf/target-cmake.in
Normal file
29
contrib/depends/packages/cmake/conf/target-cmake.in
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
echo "== Using MXE wrapper: @PREFIX@/bin/@TARGET@-cmake"
|
||||
|
||||
# https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.html
|
||||
POLICIES=(0017,0020)
|
||||
|
||||
unset NO_MXE_TOOLCHAIN
|
||||
if echo -- "$@" | grep -Ewq "(--build|-E|--system-information)" ; then
|
||||
NO_MXE_TOOLCHAIN=1
|
||||
fi
|
||||
if [[ "$NO_MXE_TOOLCHAIN" == "1" ]]; then
|
||||
echo "== Skip using MXE toolchain: @CMAKE_TOOLCHAIN_FILE@"
|
||||
# see https://github.com/mxe/mxe/issues/932
|
||||
exec "@PREFIX@/@BUILD@/bin/cmake" "$@"
|
||||
else
|
||||
echo " - cmake version @CMAKE_VERSION@"
|
||||
echo " - warnings for unused CMAKE_POLICY_DEFAULT variables can be ignored"
|
||||
echo "== Using MXE toolchain: @CMAKE_TOOLCHAIN_FILE@"
|
||||
echo "== Using MXE runresult: @CMAKE_RUNRESULT_FILE@"
|
||||
if ! ( echo "$@" | grep --silent "DCMAKE_BUILD_TYPE" ) ; then
|
||||
echo '== Adding "-DCMAKE_BUILD_TYPE=Release"'
|
||||
set -- "-DCMAKE_BUILD_TYPE=Release" "$@"
|
||||
fi
|
||||
exec "@PREFIX@/@BUILD@/bin/cmake" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="@CMAKE_TOOLCHAIN_FILE@" \
|
||||
`eval echo -DCMAKE_POLICY_DEFAULT_CMP{$POLICIES}=NEW` \
|
||||
-C"@CMAKE_RUNRESULT_FILE@" "$@"
|
||||
fi
|
||||
18
contrib/depends/packages/cmake/test/CMakeLists.txt
Normal file
18
contrib/depends/packages/cmake/test/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
# This file is part of MXE. See LICENSE.md for licensing information.
|
||||
|
||||
# 2.8.9 is Debian Wheezy version
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
# use default C and CXX languages
|
||||
project(mxe)
|
||||
|
||||
# see cmake --help-policy <cmp> for details
|
||||
cmake_policy(SET CMP0017 NEW)
|
||||
if (POLICY CMP0020)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
endif()
|
||||
|
||||
# so we can find pkg-test.cmake files to include
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../.. ${CMAKE_MODULE_PATH})
|
||||
|
||||
include(${PKG}-test)
|
||||
@@ -1,38 +0,0 @@
|
||||
package=gtest
|
||||
$(package)_version=1.8.1
|
||||
$(package)_download_path=https://github.com/google/googletest/archive/
|
||||
$(package)_file_name=release-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
|
||||
$(package)_cxxflags=-std=c++11
|
||||
$(package)_cxxflags_linux=-fPIC
|
||||
|
||||
define $(package)_config_cmds
|
||||
cd googletest && \
|
||||
CC="$(host_prefix)/native/bin/$($(package)_cc)" \
|
||||
CXX="$(host_prefix)/native/bin/$($(package)_cxx)" \
|
||||
AR="$(host_prefix)/native/bin/$($(package)_ar)" \
|
||||
RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" \
|
||||
LIBTOOL="$(host_prefix)/native/bin/$($(package)_libtool)" \
|
||||
CXXFLAGS="$($(package)_cxxflags)" \
|
||||
CCFLAGS="$($(package)_ccflags)" \
|
||||
CPPFLAGS="$($(package)_cppflags)" \
|
||||
CFLAGS="$($(package)_cflags) $($(package)_cppflags)" \
|
||||
LDLAGS="$($(package)_ldflags)" \
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) \
|
||||
-DTOOLCHAIN_PREFIX=$(host_toolchain) \
|
||||
-DCMAKE_AR="$(host_prefix)/native/bin/$($(package)_ar)" \
|
||||
-DCMAKE_RANLIB="$(host_prefix)/native/bin/$($(package)_ranlib)" \
|
||||
-DCMAKE_CXX_FLAGS_DEBUG=ON
|
||||
endef
|
||||
# -DCMAKE_TOOLCHAIN_FILE=$(HOST)/share/toolchain.cmake
|
||||
|
||||
define $(package)_build_cmds
|
||||
cd googletest && CC="$(host_prefix)/native/bin/$($(package)_cc)" $(MAKE)
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir $($(package)_staging_prefix_dir)/lib $($(package)_staging_prefix_dir)/include &&\
|
||||
cp googletest/libgtest.a $($(package)_staging_prefix_dir)/lib/ &&\
|
||||
cp googletest/libgtest_main.a $($(package)_staging_prefix_dir)/lib/ &&\
|
||||
cp -a googletest/include/* $($(package)_staging_prefix_dir)/include/
|
||||
endef
|
||||
@@ -6,7 +6,7 @@ $(package)_sha256_hash=1f912c54035533fb4268809701d65c7468d00e292efbc31e644490845
|
||||
$(package)_patches=icu-001-dont-build-static-dynamic-twice.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_build_opts=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -DU_USING_ICU_NAMESPACE=0 -DU_STATIC_IMPLEMENTATION -DU_COMBINED_IMPLEMENTATION -fPIC -DENABLE_STATIC=YES -DPGKDATA_MODE=static"
|
||||
$(package)_build_opts=CFLAGS="$($(package)_cflags) $($(package)_cppflags) -DU_USING_ICU_NAMESPACE=0 --std=gnu++0x -DU_STATIC_IMPLEMENTATION -DU_COMBINED_IMPLEMENTATION -fPIC -DENABLE_STATIC=YES -DPGKDATA_MODE=static"
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
@@ -17,7 +17,7 @@ define $(package)_config_cmds
|
||||
sh ../source/runConfigureICU Linux &&\
|
||||
make &&\
|
||||
cd ../buildb &&\
|
||||
sh ../source/runConfigureICU MinGW --enable-static=yes --disable-shared --disable-layout --disable-layoutex --disable-tests --disable-samples --prefix=$(host_prefix) --with-cross-build=`pwd`/../builda &&\
|
||||
sh ../source/$($(package)_autoconf) --enable-static=yes --disable-shared --disable-layout --disable-layoutex --disable-tests --disable-samples --prefix=$(host_prefix) --with-cross-build=`pwd`/../builda &&\
|
||||
$(MAKE) $($(package)_build_opts)
|
||||
endef
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
|
||||
cp $($(package)_extract_dir)/cctools/misc/install_name_tool $($(package)_staging_prefix_dir)/bin/ &&\
|
||||
cd $($(package)_extract_dir)/toolchain && \
|
||||
mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \
|
||||
mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package=native_cmake
|
||||
$(package)_version=3.14.0
|
||||
$(package)_version_dot=v3.14
|
||||
$(package)_download_path=https://cmake.org/files/$($(package)_version_dot)/
|
||||
$(package)_file_name=cmake-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=aa76ba67b3c2af1946701f847073f4652af5cbd9f141f221c97af99127e75502
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
./bootstrap &&\
|
||||
./configure $($(package)_config_opts)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmd
|
||||
$(MAKE)
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
@@ -15,11 +15,12 @@ define $(package)_config_cmds
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE) -C src
|
||||
$(MAKE) -C src libprotobuf.la all
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -C src install
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -C src install install-libLTLIBRARIES install-nobase_includeHEADERS &&\
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
|
||||
@@ -1,28 +1,35 @@
|
||||
package=openssl
|
||||
$(package)_version=1.0.2q
|
||||
$(package)_version=1.0.1k
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=5744cfcbcec2b1b48629f7354203bc1e5e9b5466998bbccc5b5fcde3b18eb684
|
||||
$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
||||
$(package)_config_opts+=no-camellia
|
||||
$(package)_config_opts+=no-capieng
|
||||
$(package)_config_opts+=no-cast
|
||||
$(package)_config_opts+=no-comp
|
||||
$(package)_config_opts+=no-dso
|
||||
$(package)_config_opts+=no-dtls1
|
||||
$(package)_config_opts+=no-ec_nistp_64_gcc_128
|
||||
$(package)_config_opts+=no-gost
|
||||
$(package)_config_opts+=no-gmp
|
||||
$(package)_config_opts+=no-heartbeats
|
||||
$(package)_config_opts+=no-idea
|
||||
$(package)_config_opts+=no-jpake
|
||||
$(package)_config_opts+=no-krb5
|
||||
$(package)_config_opts+=no-libunbound
|
||||
$(package)_config_opts+=no-md2
|
||||
$(package)_config_opts+=no-mdc2
|
||||
$(package)_config_opts+=no-rc4
|
||||
$(package)_config_opts+=no-rc5
|
||||
$(package)_config_opts+=no-rdrand
|
||||
$(package)_config_opts+=no-rfc3779
|
||||
$(package)_config_opts+=no-rsax
|
||||
$(package)_config_opts+=no-sctp
|
||||
$(package)_config_opts+=no-seed
|
||||
$(package)_config_opts+=no-sha0
|
||||
$(package)_config_opts+=no-shared
|
||||
$(package)_config_opts+=no-ssl-trace
|
||||
@@ -32,6 +39,7 @@ $(package)_config_opts+=no-static_engine
|
||||
$(package)_config_opts+=no-store
|
||||
$(package)_config_opts+=no-unit-test
|
||||
$(package)_config_opts+=no-weak-ssl-ciphers
|
||||
$(package)_config_opts+=no-whirlpool
|
||||
$(package)_config_opts+=no-zlib
|
||||
$(package)_config_opts+=no-zlib-dynamic
|
||||
$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
packages:=boost openssl zeromq cppzmq expat ldns cppzmq readline libiconv hidapi protobuf libusb
|
||||
packages:=boost openssl zeromq cppzmq expat ldns cppzmq readline libiconv qt hidapi protobuf libusb
|
||||
native_packages := native_ccache native_protobuf
|
||||
|
||||
darwin_native_packages = native_biplist native_ds_store native_mac_alias
|
||||
darwin_packages = sodium-darwin
|
||||
|
||||
linux_packages = eudev
|
||||
qt_packages = qt
|
||||
|
||||
ifeq ($(build_tests),ON)
|
||||
packages += gtest
|
||||
endif
|
||||
|
||||
ifeq ($(host_os),linux)
|
||||
packages += unwind
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package=readline
|
||||
$(package)_version=8.0
|
||||
$(package)_download_path=https://ftp.gnu.org/gnu/readline
|
||||
$(package)_version=6.3
|
||||
$(package)_download_path=ftp://ftp.cwru.edu/pub/bash/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461
|
||||
$(package)_sha256_hash=56ba6071b9462f980c5a72ab0023893b65ba6debb4eeb475d7a563dc65cafd43
|
||||
$(package)_patches=readline-1.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_build_opts=CC="$($(package)_cc)"
|
||||
@@ -14,6 +15,7 @@ define $(package)_set_vars
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/readline-1.patch &&\
|
||||
export bash_cv_have_mbstate_t=yes &&\
|
||||
export bash_cv_wcwidth_broken=yes &&\
|
||||
./configure $($(package)_config_opts)
|
||||
@@ -27,3 +29,5 @@ define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
endef
|
||||
|
||||
187
contrib/depends/patches/readline/readline-1.patch
Normal file
187
contrib/depends/patches/readline/readline-1.patch
Normal file
@@ -0,0 +1,187 @@
|
||||
From c0572cecbeadc8fe24c70c5c39d49210a39ac719 Mon Sep 17 00:00:00 2001
|
||||
From: Timothy Gu <timothygu99@gmail.com>
|
||||
Date: Tue, 30 Sep 2014 10:32:33 -0700
|
||||
Subject: [PATCH 1/2] signals: safeguard the remaining usage of frequently
|
||||
missing signals
|
||||
|
||||
diff --git a/input.c b/input.c
|
||||
index 117dfe8..465f0b9 100644
|
||||
--- a/input.c
|
||||
+++ b/input.c
|
||||
@@ -532,9 +532,17 @@ rl_getc (stream)
|
||||
Otherwise (not EINTR), some error occurred, also signifying EOF. */
|
||||
if (errno != EINTR)
|
||||
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
|
||||
- else if (_rl_caught_signal == SIGHUP || _rl_caught_signal == SIGTERM)
|
||||
+ else if (_rl_caught_signal == SIGTERM
|
||||
+#if defined(SIGHUP)
|
||||
+ || _rl_caught_signal == SIGHUP
|
||||
+#endif
|
||||
+ )
|
||||
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
|
||||
- else if (_rl_caught_signal == SIGINT || _rl_caught_signal == SIGQUIT)
|
||||
+ else if (_rl_caught_signal == SIGINT
|
||||
+#if defined(SIGQUIT)
|
||||
+ || _rl_caught_signal == SIGQUIT
|
||||
+#endif
|
||||
+ )
|
||||
RL_CHECK_SIGNALS ();
|
||||
|
||||
if (rl_signal_event_hook)
|
||||
diff --git a/signals.c b/signals.c
|
||||
index 61f02f9..7c921d6 100644
|
||||
--- a/signals.c
|
||||
+++ b/signals.c
|
||||
@@ -216,7 +216,9 @@ _rl_handle_signal (sig)
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case SIGTERM:
|
||||
+#if defined (SIGHUP)
|
||||
case SIGHUP:
|
||||
+#endif
|
||||
#if defined (SIGTSTP)
|
||||
case SIGTSTP:
|
||||
case SIGTTOU:
|
||||
@@ -426,7 +428,9 @@ rl_set_signals ()
|
||||
|
||||
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
|
||||
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
|
||||
+#if defined (SIGHUP)
|
||||
rl_maybe_set_sighandler (SIGHUP, rl_signal_handler, &old_hup);
|
||||
+#endif
|
||||
#if defined (SIGQUIT)
|
||||
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
|
||||
#endif
|
||||
@@ -491,7 +495,9 @@ rl_clear_signals ()
|
||||
overhead */
|
||||
rl_maybe_restore_sighandler (SIGINT, &old_int);
|
||||
rl_maybe_restore_sighandler (SIGTERM, &old_term);
|
||||
+#if defined (SIGHUP)
|
||||
rl_maybe_restore_sighandler (SIGHUP, &old_hup);
|
||||
+#endif
|
||||
#if defined (SIGQUIT)
|
||||
rl_maybe_restore_sighandler (SIGQUIT, &old_quit);
|
||||
#endif
|
||||
--
|
||||
1.8.3.2
|
||||
|
||||
|
||||
From 6896ffa4fc85bf0dfae58e69a860d2076c1d9fd2 Mon Sep 17 00:00:00 2001
|
||||
From: Timothy Gu <timothygu99@gmail.com>
|
||||
Date: Tue, 30 Sep 2014 17:16:32 -0700
|
||||
Subject: [PATCH 2/2] Handle missing S_IS* macros more gracefully
|
||||
|
||||
diff --git a/colors.c b/colors.c
|
||||
index 89d9035..ec19844 100644
|
||||
--- a/colors.c
|
||||
+++ b/colors.c
|
||||
@@ -152,14 +152,22 @@ _rl_print_color_indicator (char *f)
|
||||
{
|
||||
colored_filetype = C_FILE;
|
||||
|
||||
+#if defined (S_ISUID)
|
||||
if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
|
||||
colored_filetype = C_SETUID;
|
||||
- else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
|
||||
+ else
|
||||
+#endif
|
||||
+#if defined (S_ISGID)
|
||||
+ if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
|
||||
colored_filetype = C_SETGID;
|
||||
- else if (is_colored (C_CAP) && 0) //f->has_capability)
|
||||
+ else
|
||||
+#endif
|
||||
+ if (is_colored (C_CAP) && 0) //f->has_capability)
|
||||
colored_filetype = C_CAP;
|
||||
+#if defined(S_IXUGO)
|
||||
else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
|
||||
colored_filetype = C_EXEC;
|
||||
+#endif
|
||||
else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
|
||||
colored_filetype = C_MULTIHARDLINK;
|
||||
}
|
||||
@@ -173,8 +181,10 @@ _rl_print_color_indicator (char *f)
|
||||
colored_filetype = C_STICKY_OTHER_WRITABLE;
|
||||
else
|
||||
#endif
|
||||
+#if defined (S_IWOTH)
|
||||
if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
|
||||
colored_filetype = C_OTHER_WRITABLE;
|
||||
+#endif
|
||||
#if defined (S_ISVTX)
|
||||
else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
|
||||
colored_filetype = C_STICKY;
|
||||
diff --git a/colors.h b/colors.h
|
||||
index fc926e5..e62edd0 100644
|
||||
--- a/colors.h
|
||||
+++ b/colors.h
|
||||
@@ -96,7 +96,7 @@ enum indicator_no
|
||||
};
|
||||
|
||||
|
||||
-#if !S_IXUGO
|
||||
+#if !S_IXUGO && defined(S_IXUSR) && defined(S_IXGRP) && defined(S_IXOTH)
|
||||
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
#endif
|
||||
|
||||
diff --git a/posixstat.h b/posixstat.h
|
||||
index 3eb7f29..854a2c9 100644
|
||||
--- a/posixstat.h
|
||||
+++ b/posixstat.h
|
||||
@@ -78,30 +78,44 @@
|
||||
|
||||
#if defined (S_IFBLK) && !defined (S_ISBLK)
|
||||
#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
|
||||
+#elif !defined (S_IFBLK)
|
||||
+#define S_ISBLK(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFCHR) && !defined (S_ISCHR)
|
||||
#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
|
||||
+#elif !defined (S_IFCHR)
|
||||
+#define S_ISCHR(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFDIR) && !defined (S_ISDIR)
|
||||
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
|
||||
+#elif !defined (S_IFDIR)
|
||||
+#define S_ISDIR(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFREG) && !defined (S_ISREG)
|
||||
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
|
||||
+#elif !defined (S_IFREG)
|
||||
+#define S_ISREG(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFIFO) && !defined (S_ISFIFO)
|
||||
#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
|
||||
+#elif !defined (S_IFIFO)
|
||||
+#define S_ISFIFO(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFLNK) && !defined (S_ISLNK)
|
||||
#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
|
||||
+#elif !defined (S_IFLNK)
|
||||
+#define S_ISLNK(m) 0
|
||||
#endif
|
||||
|
||||
#if defined (S_IFSOCK) && !defined (S_ISSOCK)
|
||||
#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
|
||||
+#elif !defined (S_IFSOCK)
|
||||
+#define S_ISSOCK(m) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -137,6 +151,8 @@
|
||||
/* These are non-standard, but are used in builtins.c$symbolic_umask() */
|
||||
#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
|
||||
#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
|
||||
+#if defined(S_IXUSR) && defined(S_IXGRP) && defined(S_IXOTH)
|
||||
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
+#endif
|
||||
|
||||
#endif /* _POSIXSTAT_H_ */
|
||||
--
|
||||
1.8.3.2
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
# Set the system name, either Darwin, Linux, or Windows
|
||||
SET(CMAKE_SYSTEM_NAME @depends@)
|
||||
SET(CMAKE_BUILD_TYPE @release_type@)
|
||||
SET(CMAKE_BUILD_TYPE release)
|
||||
|
||||
OPTION(STATIC "Link libraries statically" ON)
|
||||
OPTION(TREZOR_DEBUG "Main trezor debugging switch" OFF)
|
||||
OPTION(BUILD_TESTS "Build tests." OFF)
|
||||
|
||||
SET(STATIC ON)
|
||||
SET(UNBOUND_STATIC ON)
|
||||
|
||||
SET(BUILD_TESTS @build_tests@)
|
||||
SET(TREZOR_DEBUG @build_tests@)
|
||||
SET(STATIC true)
|
||||
SET(UNBOUND_STATIC true)
|
||||
|
||||
# where is the target environment
|
||||
SET(CMAKE_FIND_ROOT_PATH @prefix@ /usr)
|
||||
@@ -54,8 +47,6 @@ set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Find programs on host
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Find libs in target
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Find includes in target
|
||||
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR} CACHE STRING "" FORCE)
|
||||
|
||||
# specify the cross compiler to be used. Darwin uses clang provided by the SDK.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
SET(CMAKE_C_COMPILER @prefix@/native/bin/clang)
|
||||
@@ -97,11 +88,6 @@ endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "i686" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
SET(LINUX_32 ON)
|
||||
SET(ARCH_ID "i386")
|
||||
endif()
|
||||
|
||||
if(ARCHITECTURE STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
SET(ARCH_ID "x86_64")
|
||||
endif()
|
||||
|
||||
#Create a new global cmake flag that indicates building with depends
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace demo
|
||||
{
|
||||
const static int ID = 1000;
|
||||
|
||||
struct request_t
|
||||
struct request
|
||||
{
|
||||
std::string example_string_data;
|
||||
some_test_data sub;
|
||||
@@ -91,10 +91,9 @@ namespace demo
|
||||
KV_SERIALIZE(sub)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
|
||||
struct response_t
|
||||
struct response
|
||||
{
|
||||
bool m_success;
|
||||
std::list<some_test_data> subs;
|
||||
@@ -105,7 +104,6 @@ namespace demo
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
|
||||
|
||||
|
||||
@@ -113,7 +111,7 @@ namespace demo
|
||||
{
|
||||
const static int ID = 1001;
|
||||
|
||||
struct request_t
|
||||
struct request
|
||||
{
|
||||
std::string example_string_data2;
|
||||
|
||||
@@ -121,9 +119,8 @@ namespace demo
|
||||
KV_SERIALIZE(example_string_data2)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
struct response
|
||||
{
|
||||
bool m_success;
|
||||
|
||||
@@ -132,7 +129,6 @@ namespace demo
|
||||
KV_SERIALIZE(m_success)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -357,7 +357,6 @@ eof:
|
||||
if (m_stdin_reader.eos())
|
||||
{
|
||||
MGINFO("EOF on stdin, exiting");
|
||||
std::cout << std::endl;
|
||||
break;
|
||||
}
|
||||
if (!get_line_ret)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include "wipeable_string.h"
|
||||
#include "span.h"
|
||||
@@ -69,10 +68,4 @@ namespace epee
|
||||
//! Write `src` bytes as hex to `out`. `out` must be twice the length
|
||||
static void buffer_unchecked(char* out, const span<const std::uint8_t> src) noexcept;
|
||||
};
|
||||
|
||||
struct from_hex
|
||||
{
|
||||
//! \return An std::vector of unsigned integers from the `src`
|
||||
static std::vector<uint8_t> vector(boost::string_ref src);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <numeric>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/random_generator.hpp>
|
||||
|
||||
@@ -243,7 +243,6 @@ namespace math_helper
|
||||
present = present << 32;
|
||||
present |= fileTime.dwLowDateTime;
|
||||
present /= 10; // mic-sec
|
||||
return present;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
||||
@@ -159,10 +159,5 @@ namespace misc_utils
|
||||
return slc;
|
||||
}
|
||||
|
||||
template<typename T> struct struct_init: T
|
||||
{
|
||||
struct_init(): T{} {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,16 +85,6 @@
|
||||
#define MGINFO_MAGENTA(x) MCLOG_MAGENTA(el::Level::Info, "global",x)
|
||||
#define MGINFO_CYAN(x) MCLOG_CYAN(el::Level::Info, "global",x)
|
||||
|
||||
#define IFLOG(level, cat, type, init, x) \
|
||||
do { \
|
||||
if (ELPP->vRegistry()->allowed(level, cat)) { \
|
||||
init; \
|
||||
el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, type).construct(cat) << x; \
|
||||
} \
|
||||
} while(0)
|
||||
#define MIDEBUG(init, x) IFLOG(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY, el::base::DispatchAction::NormalLog, init, x)
|
||||
|
||||
|
||||
#define LOG_ERROR(x) MERROR(x)
|
||||
#define LOG_PRINT_L0(x) MWARNING(x)
|
||||
#define LOG_PRINT_L1(x) MINFO(x)
|
||||
|
||||
@@ -41,12 +41,10 @@
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -89,39 +87,22 @@ namespace net_utils
|
||||
{
|
||||
public:
|
||||
typedef typename t_protocol_handler::connection_context t_connection_context;
|
||||
|
||||
struct shared_state : connection_basic_shared_state
|
||||
{
|
||||
shared_state()
|
||||
: connection_basic_shared_state(), pfilter(nullptr), config(), stop_signal_sent(false)
|
||||
{}
|
||||
|
||||
i_connection_filter* pfilter;
|
||||
typename t_protocol_handler::config_type config;
|
||||
bool stop_signal_sent;
|
||||
};
|
||||
|
||||
/// Construct a connection with the given io_service.
|
||||
|
||||
explicit connection( boost::asio::io_service& io_service,
|
||||
boost::shared_ptr<shared_state> state,
|
||||
t_connection_type connection_type,
|
||||
epee::net_utils::ssl_support_t ssl_support);
|
||||
|
||||
explicit connection( boost::asio::ip::tcp::socket&& sock,
|
||||
boost::shared_ptr<shared_state> state,
|
||||
t_connection_type connection_type,
|
||||
epee::net_utils::ssl_support_t ssl_support);
|
||||
|
||||
|
||||
typename t_protocol_handler::config_type& config,
|
||||
std::atomic<long> &ref_sock_count, // the ++/-- counter
|
||||
std::atomic<long> &sock_number, // the only increasing ++ number generator
|
||||
i_connection_filter * &pfilter
|
||||
,t_connection_type connection_type);
|
||||
|
||||
virtual ~connection() noexcept(false);
|
||||
/// Get the socket associated with the connection.
|
||||
boost::asio::ip::tcp::socket& socket();
|
||||
|
||||
/// Start the first asynchronous operation for the connection.
|
||||
bool start(bool is_income, bool is_multithreaded);
|
||||
|
||||
// `real_remote` is the actual endpoint (if connection is to proxy, etc.)
|
||||
bool start(bool is_income, bool is_multithreaded, network_address real_remote);
|
||||
|
||||
void get_context(t_connection_context& context_){context_ = context;}
|
||||
|
||||
void call_back_starter();
|
||||
@@ -147,10 +128,6 @@ namespace net_utils
|
||||
//------------------------------------------------------
|
||||
boost::shared_ptr<connection<t_protocol_handler> > safe_shared_from_this();
|
||||
bool shutdown();
|
||||
/// Handle completion of a receive operation.
|
||||
void handle_receive(const boost::system::error_code& e,
|
||||
std::size_t bytes_transferred);
|
||||
|
||||
/// Handle completion of a read operation.
|
||||
void handle_read(const boost::system::error_code& e,
|
||||
std::size_t bytes_transferred);
|
||||
@@ -168,9 +145,10 @@ namespace net_utils
|
||||
|
||||
/// Buffer for incoming data.
|
||||
boost::array<char, 8192> buffer_;
|
||||
size_t buffer_ssl_init_fill;
|
||||
//boost::array<char, 1024> buffer_;
|
||||
|
||||
t_connection_context context;
|
||||
i_connection_filter* &m_pfilter;
|
||||
|
||||
// TODO what do they mean about wait on destructor?? --rfree :
|
||||
//this should be the last one, because it could be wait on destructor, while other activities possible on other threads
|
||||
@@ -207,13 +185,6 @@ namespace net_utils
|
||||
class boosted_tcp_server
|
||||
: private boost::noncopyable
|
||||
{
|
||||
enum try_connect_result_t
|
||||
{
|
||||
CONNECT_SUCCESS,
|
||||
CONNECT_FAILURE,
|
||||
CONNECT_NO_SSL,
|
||||
};
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<connection<t_protocol_handler> > connection_ptr;
|
||||
typedef typename t_protocol_handler::connection_context t_connection_context;
|
||||
@@ -227,8 +198,8 @@ namespace net_utils
|
||||
std::map<std::string, t_connection_type> server_type_map;
|
||||
void create_server_type_map();
|
||||
|
||||
bool init_server(uint32_t port, const std::string address = "0.0.0.0", ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect);
|
||||
bool init_server(const std::string port, const std::string& address = "0.0.0.0", ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect);
|
||||
bool init_server(uint32_t port, const std::string address = "0.0.0.0");
|
||||
bool init_server(const std::string port, const std::string& address = "0.0.0.0");
|
||||
|
||||
/// Run the server's io_service loop.
|
||||
bool run_server(size_t threads_count, bool wait = true, const boost::thread::attributes& attrs = boost::thread::attributes());
|
||||
@@ -239,9 +210,7 @@ namespace net_utils
|
||||
/// Stop the server.
|
||||
void send_stop_signal();
|
||||
|
||||
bool is_stop_signal_sent() const noexcept { return m_stop_signal_sent; };
|
||||
|
||||
const std::atomic<bool>& get_stop_signal() const noexcept { return m_stop_signal_sent; }
|
||||
bool is_stop_signal_sent();
|
||||
|
||||
void set_threads_prefix(const std::string& prefix_name);
|
||||
|
||||
@@ -251,29 +220,17 @@ namespace net_utils
|
||||
|
||||
void set_connection_filter(i_connection_filter* pfilter);
|
||||
|
||||
void set_default_remote(epee::net_utils::network_address remote)
|
||||
{
|
||||
default_remote = std::move(remote);
|
||||
}
|
||||
|
||||
bool add_connection(t_connection_context& out, boost::asio::ip::tcp::socket&& sock, network_address real_remote, epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
||||
try_connect_result_t try_connect(connection_ptr new_connection_l, const std::string& adr, const std::string& port, boost::asio::ip::tcp::socket &sock_, const boost::asio::ip::tcp::endpoint &remote_endpoint, const std::string &bind_ip, uint32_t conn_timeout, epee::net_utils::ssl_support_t ssl_support);
|
||||
bool connect(const std::string& adr, const std::string& port, uint32_t conn_timeot, t_connection_context& cn, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
||||
bool connect(const std::string& adr, const std::string& port, uint32_t conn_timeot, t_connection_context& cn, const std::string& bind_ip = "0.0.0.0");
|
||||
template<class t_callback>
|
||||
bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0", epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
||||
bool connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeot, const t_callback &cb, const std::string& bind_ip = "0.0.0.0");
|
||||
|
||||
typename t_protocol_handler::config_type& get_config_object()
|
||||
{
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
return m_state->config;
|
||||
}
|
||||
typename t_protocol_handler::config_type& get_config_object(){return m_config;}
|
||||
|
||||
int get_binded_port(){return m_port;}
|
||||
|
||||
long get_connections_count() const
|
||||
{
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
auto connections_count = m_state->sock_count > 0 ? (m_state->sock_count - 1) : 0; // Socket count minus listening socket
|
||||
auto connections_count = (m_sock_count > 0) ? (m_sock_count - 1) : 0; // Socket count minus listening socket
|
||||
return connections_count;
|
||||
}
|
||||
|
||||
@@ -335,6 +292,9 @@ namespace net_utils
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
typename t_protocol_handler::config_type m_config;
|
||||
|
||||
private:
|
||||
/// Run the server's io_service loop.
|
||||
bool worker_thread();
|
||||
@@ -343,30 +303,21 @@ namespace net_utils
|
||||
|
||||
bool is_thread_worker();
|
||||
|
||||
const boost::shared_ptr<typename connection<t_protocol_handler>::shared_state> m_state;
|
||||
|
||||
/// The io_service used to perform asynchronous operations.
|
||||
struct worker
|
||||
{
|
||||
worker()
|
||||
: io_service(), work(io_service)
|
||||
{}
|
||||
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::io_service::work work;
|
||||
};
|
||||
std::unique_ptr<worker> m_io_service_local_instance;
|
||||
std::unique_ptr<boost::asio::io_service> m_io_service_local_instance;
|
||||
boost::asio::io_service& io_service_;
|
||||
|
||||
/// Acceptor used to listen for incoming connections.
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
epee::net_utils::network_address default_remote;
|
||||
|
||||
std::atomic<bool> m_stop_signal_sent;
|
||||
uint32_t m_port;
|
||||
std::atomic<long> m_sock_count;
|
||||
std::atomic<long> m_sock_number;
|
||||
std::string m_address;
|
||||
std::string m_thread_name_prefix; //TODO: change to enum server_type, now used
|
||||
size_t m_threads_count;
|
||||
i_connection_filter* m_pfilter;
|
||||
std::vector<boost::shared_ptr<boost::thread> > m_threads;
|
||||
boost::thread::id m_main_thread_id;
|
||||
critical_section m_threads_lock;
|
||||
@@ -379,6 +330,7 @@ namespace net_utils
|
||||
|
||||
boost::mutex connections_mutex;
|
||||
std::set<connection_ptr> connections_;
|
||||
|
||||
}; // class <>boosted_tcp_server
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
|
||||
#include <boost/thread/condition_variable.hpp> // TODO
|
||||
#include <boost/make_shared.hpp>
|
||||
#include "warnings.h"
|
||||
#include "string_tools.h"
|
||||
#include "misc_language.h"
|
||||
@@ -58,19 +57,11 @@
|
||||
#define DEFAULT_TIMEOUT_MS_REMOTE 300000 // 5 minutes
|
||||
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
|
||||
|
||||
|
||||
PRAGMA_WARNING_PUSH
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
template<typename T>
|
||||
T& check_and_get(boost::shared_ptr<T>& ptr)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(bool(ptr), "shared_state cannot be null");
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
@@ -78,34 +69,25 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
template<class t_protocol_handler>
|
||||
connection<t_protocol_handler>::connection( boost::asio::io_service& io_service,
|
||||
boost::shared_ptr<shared_state> state,
|
||||
t_connection_type connection_type,
|
||||
ssl_support_t ssl_support
|
||||
)
|
||||
: connection(boost::asio::ip::tcp::socket{io_service}, std::move(state), connection_type, ssl_support)
|
||||
{
|
||||
}
|
||||
|
||||
template<class t_protocol_handler>
|
||||
connection<t_protocol_handler>::connection( boost::asio::ip::tcp::socket&& sock,
|
||||
boost::shared_ptr<shared_state> state,
|
||||
t_connection_type connection_type,
|
||||
ssl_support_t ssl_support
|
||||
typename t_protocol_handler::config_type& config,
|
||||
std::atomic<long> &ref_sock_count, // the ++/-- counter
|
||||
std::atomic<long> &sock_number, // the only increasing ++ number generator
|
||||
i_connection_filter* &pfilter
|
||||
,t_connection_type connection_type
|
||||
)
|
||||
:
|
||||
connection_basic(std::move(sock), state, ssl_support),
|
||||
m_protocol_handler(this, check_and_get(state).config, context),
|
||||
buffer_ssl_init_fill(0),
|
||||
connection_basic(io_service, ref_sock_count, sock_number),
|
||||
m_protocol_handler(this, config, context),
|
||||
m_pfilter( pfilter ),
|
||||
m_connection_type( connection_type ),
|
||||
m_throttle_speed_in("speed_in", "throttle_speed_in"),
|
||||
m_throttle_speed_out("speed_out", "throttle_speed_out"),
|
||||
m_timer(GET_IO_SERVICE(socket_)),
|
||||
m_timer(io_service),
|
||||
m_local(false),
|
||||
m_ready_to_close(false)
|
||||
{
|
||||
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
|
||||
}
|
||||
|
||||
PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
@@ -113,11 +95,17 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
{
|
||||
if(!m_was_shutdown)
|
||||
{
|
||||
_dbg3("[sock " << socket().native_handle() << "] Socket destroyed without shutdown.");
|
||||
_dbg3("[sock " << socket_.native_handle() << "] Socket destroyed without shutdown.");
|
||||
shutdown();
|
||||
}
|
||||
|
||||
_dbg3("[sock " << socket().native_handle() << "] Socket destroyed");
|
||||
_dbg3("[sock " << socket_.native_handle() << "] Socket destroyed");
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
boost::asio::ip::tcp::socket& connection<t_protocol_handler>::socket()
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
@@ -139,47 +127,36 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
boost::system::error_code ec;
|
||||
auto remote_ep = socket().remote_endpoint(ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get remote endpoint: " << ec.message() << ':' << ec.value());
|
||||
CHECK_AND_NO_ASSERT_MES(remote_ep.address().is_v4(), false, "IPv6 not supported here");
|
||||
|
||||
const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())};
|
||||
return start(is_income, is_multithreaded, ipv4_network_address{uint32_t(ip_), remote_ep.port()});
|
||||
CATCH_ENTRY_L0("connection<t_protocol_handler>::start()", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool connection<t_protocol_handler>::start(bool is_income, bool is_multithreaded, network_address real_remote)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
// Use safe_shared_from_this, because of this is public method and it can be called on the object being deleted
|
||||
auto self = safe_shared_from_this();
|
||||
if(!self)
|
||||
return false;
|
||||
|
||||
m_is_multithreaded = is_multithreaded;
|
||||
m_local = real_remote.is_loopback() || real_remote.is_local();
|
||||
|
||||
boost::system::error_code ec;
|
||||
auto remote_ep = socket_.remote_endpoint(ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get remote endpoint: " << ec.message() << ':' << ec.value());
|
||||
CHECK_AND_NO_ASSERT_MES(remote_ep.address().is_v4(), false, "IPv6 not supported here");
|
||||
|
||||
auto local_ep = socket_.local_endpoint(ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value());
|
||||
|
||||
context = boost::value_initialized<t_connection_context>();
|
||||
const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())};
|
||||
m_local = epee::net_utils::is_ip_loopback(ip_) || epee::net_utils::is_ip_local(ip_);
|
||||
|
||||
// create a random uuid, we don't need crypto strength here
|
||||
const boost::uuids::uuid random_uuid = boost::uuids::random_generator()();
|
||||
|
||||
context = t_connection_context{};
|
||||
bool ssl = m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled;
|
||||
context.set_details(random_uuid, std::move(real_remote), is_income, ssl);
|
||||
|
||||
boost::system::error_code ec;
|
||||
auto local_ep = socket().local_endpoint(ec);
|
||||
CHECK_AND_NO_ASSERT_MES(!ec, false, "Failed to get local endpoint: " << ec.message() << ':' << ec.value());
|
||||
|
||||
context.set_details(random_uuid, epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income);
|
||||
_dbg3("[sock " << socket_.native_handle() << "] new connection from " << print_connection_context_short(context) <<
|
||||
" to " << local_ep.address().to_string() << ':' << local_ep.port() <<
|
||||
", total sockets objects " << get_state().sock_count);
|
||||
", total sockets objects " << m_ref_sock_count);
|
||||
|
||||
if(static_cast<shared_state&>(get_state()).pfilter && !static_cast<shared_state&>(get_state()).pfilter->is_remote_host_allowed(context.m_remote_address))
|
||||
if(m_pfilter && !m_pfilter->is_remote_host_allowed(context.m_remote_address))
|
||||
{
|
||||
_dbg2("[sock " << socket().native_handle() << "] host denied " << context.m_remote_address.host_str() << ", shutdowning connection");
|
||||
_dbg2("[sock " << socket_.native_handle() << "] host denied " << context.m_remote_address.host_str() << ", shutdowning connection");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
@@ -191,21 +168,11 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
reset_timer(get_default_timeout(), false);
|
||||
|
||||
// first read on the raw socket to detect SSL for the server
|
||||
buffer_ssl_init_fill = 0;
|
||||
if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled)
|
||||
socket().async_receive(boost::asio::buffer(buffer_),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_receive, self,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
else
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_read, self,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
socket_.async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_read, self,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
#if !defined(_WIN32) || !defined(__i686)
|
||||
// not supported before Windows7, too lazy for runtime check
|
||||
// Just exclude for 32bit windows builds
|
||||
@@ -213,12 +180,12 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
int tos = get_tos_flag();
|
||||
boost::asio::detail::socket_option::integer< IPPROTO_IP, IP_TOS >
|
||||
optionTos( tos );
|
||||
socket().set_option( optionTos );
|
||||
socket_.set_option( optionTos );
|
||||
//_dbg1("Set ToS flag to " << tos);
|
||||
#endif
|
||||
|
||||
boost::asio::ip::tcp::no_delay noDelayOption(false);
|
||||
socket().set_option(noDelayOption);
|
||||
socket_.set_option(noDelayOption);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -243,7 +210,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
template<class t_protocol_handler>
|
||||
boost::asio::io_service& connection<t_protocol_handler>::get_io_service()
|
||||
{
|
||||
return GET_IO_SERVICE(socket());
|
||||
return socket_.get_io_service();
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
@@ -255,9 +222,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
auto self = safe_shared_from_this();
|
||||
if(!self)
|
||||
return false;
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
|
||||
//_dbg3("[sock " << socket_.native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
|
||||
CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
|
||||
//_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
|
||||
//_dbg3("[sock " << socket_.native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
|
||||
if(m_was_shutdown)
|
||||
return false;
|
||||
++m_reference_count;
|
||||
@@ -271,9 +238,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
boost::shared_ptr<connection<t_protocol_handler> > back_connection_copy;
|
||||
LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] release");
|
||||
LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] release");
|
||||
CRITICAL_REGION_BEGIN(m_self_refs_lock);
|
||||
CHECK_AND_ASSERT_MES(m_reference_count, false, "[sock " << socket().native_handle() << "] m_reference_count already at 0 at connection<t_protocol_handler>::release() call");
|
||||
CHECK_AND_ASSERT_MES(m_reference_count, false, "[sock " << socket_.native_handle() << "] m_reference_count already at 0 at connection<t_protocol_handler>::release() call");
|
||||
// is this the last reference?
|
||||
if (--m_reference_count == 0) {
|
||||
// move the held reference to a local variable, keeping the object alive until the function terminates
|
||||
@@ -299,7 +266,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
std::string address, port;
|
||||
boost::system::error_code e;
|
||||
|
||||
boost::asio::ip::tcp::endpoint endpoint = socket().remote_endpoint(e);
|
||||
boost::asio::ip::tcp::endpoint endpoint = socket_.remote_endpoint(e);
|
||||
if (e)
|
||||
{
|
||||
address = "<not connected>";
|
||||
@@ -311,8 +278,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
port = boost::lexical_cast<std::string>(endpoint.port());
|
||||
}
|
||||
MDEBUG(" connection type " << to_string( m_connection_type ) << " "
|
||||
<< socket().local_endpoint().address().to_string() << ":" << socket().local_endpoint().port()
|
||||
<< " <--> " << context.m_remote_address.str() << " (via " << address << ":" << port << ")");
|
||||
<< socket_.local_endpoint().address().to_string() << ":" << socket_.local_endpoint().port()
|
||||
<< " <--> " << address << ":" << port);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
@@ -320,7 +287,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
//_info("[sock " << socket().native_handle() << "] Async read calledback.");
|
||||
//_info("[sock " << socket_.native_handle() << "] Async read calledback.");
|
||||
|
||||
if (!e)
|
||||
{
|
||||
@@ -328,7 +295,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CRITICAL_REGION_LOCAL(m_throttle_speed_in_mutex);
|
||||
m_throttle_speed_in.handle_trafic_exact(bytes_transferred);
|
||||
context.m_current_speed_down = m_throttle_speed_in.get_current_speed();
|
||||
context.m_max_speed_down = std::max(context.m_max_speed_down, context.m_current_speed_down);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -356,7 +322,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
} while(delay > 0);
|
||||
} // any form of sleeping
|
||||
|
||||
//_info("[sock " << socket().native_handle() << "] RECV " << bytes_transferred);
|
||||
//_info("[sock " << socket_.native_handle() << "] RECV " << bytes_transferred);
|
||||
logger_handle_net_read(bytes_transferred);
|
||||
context.m_last_recv = time(NULL);
|
||||
context.m_recv_cnt += bytes_transferred;
|
||||
@@ -364,7 +330,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
bool recv_res = m_protocol_handler.handle_recv(buffer_.data(), bytes_transferred);
|
||||
if(!recv_res)
|
||||
{
|
||||
//_info("[sock " << socket().native_handle() << "] protocol_want_close");
|
||||
//_info("[sock " << socket_.native_handle() << "] protocol_want_close");
|
||||
|
||||
//some error in protocol, protocol handler ask to close connection
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1);
|
||||
@@ -378,24 +344,24 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
}else
|
||||
{
|
||||
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
socket_.async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
//_info("[sock " << socket().native_handle() << "]Async read requested.");
|
||||
//_info("[sock " << socket_.native_handle() << "]Async read requested.");
|
||||
}
|
||||
}else
|
||||
{
|
||||
_dbg3("[sock " << socket().native_handle() << "] Some not success at read: " << e.message() << ':' << e.value());
|
||||
_dbg3("[sock " << socket_.native_handle() << "] Some not success at read: " << e.message() << ':' << e.value());
|
||||
if(e.value() != 2)
|
||||
{
|
||||
_dbg3("[sock " << socket().native_handle() << "] Some problems at read: " << e.message() << ':' << e.value());
|
||||
_dbg3("[sock " << socket_.native_handle() << "] Some problems at read: " << e.message() << ':' << e.value());
|
||||
shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbg3("[sock " << socket().native_handle() << "] peer closed connection");
|
||||
_dbg3("[sock " << socket_.native_handle() << "] peer closed connection");
|
||||
if (m_ready_to_close)
|
||||
shutdown();
|
||||
}
|
||||
@@ -409,85 +375,13 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
void connection<t_protocol_handler>::handle_receive(const boost::system::error_code& e,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if (e)
|
||||
{
|
||||
// offload the error case
|
||||
handle_read(e, bytes_transferred);
|
||||
return;
|
||||
}
|
||||
|
||||
reset_timer(get_timeout_from_bytes_read(bytes_transferred), false);
|
||||
|
||||
buffer_ssl_init_fill += bytes_transferred;
|
||||
if (buffer_ssl_init_fill <= get_ssl_magic_size())
|
||||
{
|
||||
socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill),
|
||||
boost::asio::socket_base::message_peek,
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_receive, connection<t_protocol_handler>::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
return;
|
||||
}
|
||||
|
||||
// detect SSL
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
if (is_ssl((const unsigned char*)buffer_.data(), buffer_ssl_init_fill))
|
||||
{
|
||||
MDEBUG("That looks like SSL");
|
||||
m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; // read/write to the SSL socket
|
||||
}
|
||||
else
|
||||
{
|
||||
MDEBUG("That does not look like SSL");
|
||||
m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; // read/write to the raw socket
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
{
|
||||
// Handshake
|
||||
if (!handshake(boost::asio::ssl::stream_base::server))
|
||||
{
|
||||
MERROR("SSL handshake failed");
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1);
|
||||
bool do_shutdown = false;
|
||||
CRITICAL_REGION_BEGIN(m_send_que_lock);
|
||||
if(!m_send_que.size())
|
||||
do_shutdown = true;
|
||||
CRITICAL_REGION_END();
|
||||
if(do_shutdown)
|
||||
shutdown();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async_read_some(boost::asio::buffer(buffer_),
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_read, connection<t_protocol_handler>::shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
|
||||
// If an error occurs then no new asynchronous operations are started. This
|
||||
// means that all shared_ptr references to the connection object will
|
||||
// disappear and the object will be destroyed automatically after this
|
||||
// handler returns. The connection class's destructor closes the socket.
|
||||
CATCH_ENTRY_L0("connection<t_protocol_handler>::handle_receive", void());
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool connection<t_protocol_handler>::call_run_once_service_io()
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!m_is_multithreaded)
|
||||
{
|
||||
//single thread model, we can wait in blocked call
|
||||
size_t cnt = GET_IO_SERVICE(socket()).run_one();
|
||||
size_t cnt = socket_.get_io_service().run_one();
|
||||
if(!cnt)//service is going to quit
|
||||
return false;
|
||||
}else
|
||||
@@ -497,7 +391,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
//if no handlers were called
|
||||
//TODO: Maybe we need to have have critical section + event + callback to upper protocol to
|
||||
//ask it inside(!) critical region if we still able to go in event wait...
|
||||
size_t cnt = GET_IO_SERVICE(socket()).poll_one();
|
||||
size_t cnt = socket_.get_io_service().poll_one();
|
||||
if(!cnt)
|
||||
misc_utils::sleep_no_w(1);
|
||||
}
|
||||
@@ -603,10 +497,9 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CRITICAL_REGION_LOCAL(m_throttle_speed_out_mutex);
|
||||
m_throttle_speed_out.handle_trafic_exact(cb);
|
||||
context.m_current_speed_up = m_throttle_speed_out.get_current_speed();
|
||||
context.m_max_speed_up = std::max(context.m_max_speed_up, context.m_current_speed_up);
|
||||
}
|
||||
|
||||
//_info("[sock " << socket().native_handle() << "] SEND " << cb);
|
||||
//_info("[sock " << socket_.native_handle() << "] SEND " << cb);
|
||||
context.m_last_send = time(NULL);
|
||||
context.m_send_cnt += cb;
|
||||
//some data should be wrote to stream
|
||||
@@ -651,7 +544,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
MDEBUG("do_send_chunk() NOW just queues: packet="<<size_now<<" B, is added to queue-size="<<m_send_que.size());
|
||||
//do_send_handler_delayed( ptr , size_now ); // (((H))) // empty function
|
||||
|
||||
LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] Async send requested " << m_send_que.front().size());
|
||||
LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] Async send requested " << m_send_que.front().size());
|
||||
}
|
||||
else
|
||||
{ // no active operation
|
||||
@@ -669,14 +562,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), false, "Unexpected queue size");
|
||||
reset_timer(get_default_timeout(), false);
|
||||
async_write(boost::asio::buffer(m_send_que.front().data(), size_now ) ,
|
||||
strand_.wrap(
|
||||
boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now ) ,
|
||||
//strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_write, self, _1, _2)
|
||||
)
|
||||
//)
|
||||
);
|
||||
//_dbg3("(chunk): " << size_now);
|
||||
//logger_handle_net_write(size_now);
|
||||
//_info("[sock " << socket().native_handle() << "] Async send requested " << m_send_que.front().size());
|
||||
//_info("[sock " << socket_.native_handle() << "] Async send requested " << m_send_que.front().size());
|
||||
}
|
||||
|
||||
//do_send_handler_stop( ptr , cb ); // empty function
|
||||
@@ -761,13 +654,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
// Initiate graceful connection closure.
|
||||
m_timer.cancel();
|
||||
boost::system::error_code ignored_ec;
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
{
|
||||
const shared_state &state = static_cast<const shared_state&>(get_state());
|
||||
if (!state.stop_signal_sent)
|
||||
socket_.shutdown(ignored_ec);
|
||||
}
|
||||
socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
if (!m_host.empty())
|
||||
{
|
||||
try { host_count(m_host, -1); } catch (...) { /* ignore */ }
|
||||
@@ -785,7 +672,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
auto self = safe_shared_from_this();
|
||||
if(!self)
|
||||
return false;
|
||||
//_info("[sock " << socket().native_handle() << "] Que Shutdown called.");
|
||||
//_info("[sock " << socket_.native_handle() << "] Que Shutdown called.");
|
||||
m_timer.cancel();
|
||||
size_t send_que_size = 0;
|
||||
CRITICAL_REGION_BEGIN(m_send_que_lock);
|
||||
@@ -820,11 +707,11 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
void connection<t_protocol_handler>::handle_write(const boost::system::error_code& e, size_t cb)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_TRACE_CC(context, "[sock " << socket().native_handle() << "] Async send calledback " << cb);
|
||||
LOG_TRACE_CC(context, "[sock " << socket_.native_handle() << "] Async send calledback " << cb);
|
||||
|
||||
if (e)
|
||||
{
|
||||
_dbg1("[sock " << socket().native_handle() << "] Some problems at write: " << e.message() << ':' << e.value());
|
||||
_dbg1("[sock " << socket_.native_handle() << "] Some problems at write: " << e.message() << ':' << e.value());
|
||||
shutdown();
|
||||
return;
|
||||
}
|
||||
@@ -839,7 +726,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
CRITICAL_REGION_BEGIN(m_send_que_lock);
|
||||
if(m_send_que.empty())
|
||||
{
|
||||
_erro("[sock " << socket().native_handle() << "] m_send_que.size() == 0 at handle_write!");
|
||||
_erro("[sock " << socket_.native_handle() << "] m_send_que.size() == 0 at handle_write!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -859,11 +746,11 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
if (speed_limit_is_enabled())
|
||||
do_send_handler_write_from_queue(e, m_send_que.front().size() , m_send_que.size()); // (((H)))
|
||||
CHECK_AND_ASSERT_MES( size_now == m_send_que.front().size(), void(), "Unexpected queue size");
|
||||
async_write(boost::asio::buffer(m_send_que.front().data(), size_now) ,
|
||||
strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), _1, _2)
|
||||
)
|
||||
);
|
||||
boost::asio::async_write(socket_, boost::asio::buffer(m_send_que.front().data(), size_now) ,
|
||||
// strand_.wrap(
|
||||
boost::bind(&connection<t_protocol_handler>::handle_write, connection<t_protocol_handler>::shared_from_this(), _1, _2)
|
||||
// )
|
||||
);
|
||||
//_dbg3("(normal)" << size_now);
|
||||
}
|
||||
CRITICAL_REGION_END();
|
||||
@@ -895,14 +782,12 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
template<class t_protocol_handler>
|
||||
boosted_tcp_server<t_protocol_handler>::boosted_tcp_server( t_connection_type connection_type ) :
|
||||
m_state(boost::make_shared<typename connection<t_protocol_handler>::shared_state>()),
|
||||
m_io_service_local_instance(new worker()),
|
||||
io_service_(m_io_service_local_instance->io_service),
|
||||
m_io_service_local_instance(new boost::asio::io_service()),
|
||||
io_service_(*m_io_service_local_instance.get()),
|
||||
acceptor_(io_service_),
|
||||
default_remote(),
|
||||
m_stop_signal_sent(false), m_port(0),
|
||||
m_threads_count(0),
|
||||
m_thread_index(0),
|
||||
m_sock_count(0), m_sock_number(0), m_threads_count(0),
|
||||
m_pfilter(NULL), m_thread_index(0),
|
||||
m_connection_type( connection_type ),
|
||||
new_connection_()
|
||||
{
|
||||
@@ -912,13 +797,11 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
|
||||
template<class t_protocol_handler>
|
||||
boosted_tcp_server<t_protocol_handler>::boosted_tcp_server(boost::asio::io_service& extarnal_io_service, t_connection_type connection_type) :
|
||||
m_state(boost::make_shared<typename connection<t_protocol_handler>::shared_state>()),
|
||||
io_service_(extarnal_io_service),
|
||||
acceptor_(io_service_),
|
||||
default_remote(),
|
||||
m_stop_signal_sent(false), m_port(0),
|
||||
m_threads_count(0),
|
||||
m_thread_index(0),
|
||||
m_stop_signal_sent(false), m_port(0),
|
||||
m_sock_count(0), m_sock_number(0), m_threads_count(0),
|
||||
m_pfilter(NULL), m_thread_index(0),
|
||||
m_connection_type(connection_type),
|
||||
new_connection_()
|
||||
{
|
||||
@@ -942,14 +825,12 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool boosted_tcp_server<t_protocol_handler>::init_server(uint32_t port, const std::string address, ssl_options_t ssl_options)
|
||||
bool boosted_tcp_server<t_protocol_handler>::init_server(uint32_t port, const std::string address)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
m_stop_signal_sent = false;
|
||||
m_port = port;
|
||||
m_address = address;
|
||||
if (ssl_options)
|
||||
m_state->configure_ssl(std::move(ssl_options));
|
||||
// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
|
||||
boost::asio::ip::tcp::resolver resolver(io_service_);
|
||||
boost::asio::ip::tcp::resolver::query query(address, boost::lexical_cast<std::string>(port), boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
@@ -961,7 +842,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_.local_endpoint();
|
||||
m_port = binded_endpoint.port();
|
||||
MDEBUG("start accept");
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, m_state->ssl_options().support));
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type));
|
||||
acceptor_.async_accept(new_connection_->socket(),
|
||||
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
||||
boost::asio::placeholders::error));
|
||||
@@ -983,7 +864,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
PUSH_WARNINGS
|
||||
DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
template<class t_protocol_handler>
|
||||
bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address, ssl_options_t ssl_options)
|
||||
bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address)
|
||||
{
|
||||
uint32_t p = 0;
|
||||
|
||||
@@ -991,7 +872,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
MERROR("Failed to convert port no = " << port);
|
||||
return false;
|
||||
}
|
||||
return this->init_server(p, address, std::move(ssl_options));
|
||||
return this->init_server(p, address);
|
||||
}
|
||||
POP_WARNINGS
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -1008,8 +889,9 @@ POP_WARNINGS
|
||||
{
|
||||
try
|
||||
{
|
||||
io_service_.run();
|
||||
return true;
|
||||
size_t cnt = io_service_.run();
|
||||
if (cnt == 0)
|
||||
misc_utils::sleep_no_w(1);
|
||||
}
|
||||
catch(const std::exception& ex)
|
||||
{
|
||||
@@ -1038,8 +920,7 @@ POP_WARNINGS
|
||||
template<class t_protocol_handler>
|
||||
void boosted_tcp_server<t_protocol_handler>::set_connection_filter(i_connection_filter* pfilter)
|
||||
{
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
m_state->pfilter = pfilter;
|
||||
m_pfilter = pfilter;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
@@ -1134,8 +1015,6 @@ POP_WARNINGS
|
||||
void boosted_tcp_server<t_protocol_handler>::send_stop_signal()
|
||||
{
|
||||
m_stop_signal_sent = true;
|
||||
typename connection<t_protocol_handler>::shared_state *state = static_cast<typename connection<t_protocol_handler>::shared_state*>(m_state.get());
|
||||
state->stop_signal_sent = true;
|
||||
TRY_ENTRY();
|
||||
connections_mutex.lock();
|
||||
for (auto &c: connections_)
|
||||
@@ -1149,6 +1028,12 @@ POP_WARNINGS
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool boosted_tcp_server<t_protocol_handler>::is_stop_signal_sent()
|
||||
{
|
||||
return m_stop_signal_sent;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
void boosted_tcp_server<t_protocol_handler>::handle_accept(const boost::system::error_code& e)
|
||||
{
|
||||
MDEBUG("handle_accept");
|
||||
@@ -1157,18 +1042,11 @@ POP_WARNINGS
|
||||
if (!e)
|
||||
{
|
||||
if (m_connection_type == e_connection_type_RPC) {
|
||||
const char *ssl_message = "unknown";
|
||||
switch (new_connection_->get_ssl_support())
|
||||
{
|
||||
case epee::net_utils::ssl_support_t::e_ssl_support_disabled: ssl_message = "disabled"; break;
|
||||
case epee::net_utils::ssl_support_t::e_ssl_support_enabled: ssl_message = "enabled"; break;
|
||||
case epee::net_utils::ssl_support_t::e_ssl_support_autodetect: ssl_message = "autodetection"; break;
|
||||
}
|
||||
MDEBUG("New server for RPC connections, SSL " << ssl_message);
|
||||
MDEBUG("New server for RPC connections");
|
||||
new_connection_->setRpcStation(); // hopefully this is not needed actually
|
||||
}
|
||||
connection_ptr conn(std::move(new_connection_));
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, conn->get_ssl_support()));
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type));
|
||||
acceptor_.async_accept(new_connection_->socket(),
|
||||
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
||||
boost::asio::placeholders::error));
|
||||
@@ -1176,16 +1054,7 @@ POP_WARNINGS
|
||||
boost::asio::socket_base::keep_alive opt(true);
|
||||
conn->socket().set_option(opt);
|
||||
|
||||
bool res;
|
||||
if (default_remote.get_type_id() == net_utils::address_type::invalid)
|
||||
res = conn->start(true, 1 < m_threads_count);
|
||||
else
|
||||
res = conn->start(true, 1 < m_threads_count, default_remote);
|
||||
if (!res)
|
||||
{
|
||||
conn->cancel();
|
||||
return;
|
||||
}
|
||||
conn->start(true, 1 < m_threads_count);
|
||||
conn->save_dbg_log();
|
||||
return;
|
||||
}
|
||||
@@ -1200,40 +1069,43 @@ POP_WARNINGS
|
||||
}
|
||||
|
||||
// error path, if e or exception
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
_erro("Some problems at accept: " << e.message() << ", connections_count = " << m_state->sock_count);
|
||||
_erro("Some problems at accept: " << e.message() << ", connections_count = " << m_sock_count);
|
||||
misc_utils::sleep_no_w(100);
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, new_connection_->get_ssl_support()));
|
||||
new_connection_.reset(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type));
|
||||
acceptor_.async_accept(new_connection_->socket(),
|
||||
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
||||
boost::asio::placeholders::error));
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool boosted_tcp_server<t_protocol_handler>::add_connection(t_connection_context& out, boost::asio::ip::tcp::socket&& sock, network_address real_remote, epee::net_utils::ssl_support_t ssl_support)
|
||||
{
|
||||
if(std::addressof(get_io_service()) == std::addressof(GET_IO_SERVICE(sock)))
|
||||
{
|
||||
connection_ptr conn(new connection<t_protocol_handler>(std::move(sock), m_state, m_connection_type, ssl_support));
|
||||
if(conn->start(false, 1 < m_threads_count, std::move(real_remote)))
|
||||
{
|
||||
conn->get_context(out);
|
||||
conn->save_dbg_log();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MWARNING(out << " was not added, socket/io_service mismatch");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
typename boosted_tcp_server<t_protocol_handler>::try_connect_result_t boosted_tcp_server<t_protocol_handler>::try_connect(connection_ptr new_connection_l, const std::string& adr, const std::string& port, boost::asio::ip::tcp::socket &sock_, const boost::asio::ip::tcp::endpoint &remote_endpoint, const std::string &bind_ip, uint32_t conn_timeout, epee::net_utils::ssl_support_t ssl_support)
|
||||
bool boosted_tcp_server<t_protocol_handler>::connect(const std::string& adr, const std::string& port, uint32_t conn_timeout, t_connection_context& conn_context, const std::string& bind_ip)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type) );
|
||||
connections_mutex.lock();
|
||||
connections_.insert(new_connection_l);
|
||||
MDEBUG("connections_ size now " << connections_.size());
|
||||
connections_mutex.unlock();
|
||||
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); });
|
||||
boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
boost::asio::ip::tcp::resolver resolver(io_service_);
|
||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if(iterator == end)
|
||||
{
|
||||
_erro("Failed to resolve " << adr);
|
||||
return false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port);
|
||||
boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
|
||||
|
||||
sock_.open(remote_endpoint.protocol());
|
||||
if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" )
|
||||
{
|
||||
@@ -1245,7 +1117,7 @@ POP_WARNINGS
|
||||
MERROR("Error binding to " << bind_ip << ": " << ec.message());
|
||||
if (sock_.is_open())
|
||||
sock_.close();
|
||||
return CONNECT_FAILURE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1279,14 +1151,14 @@ POP_WARNINGS
|
||||
{
|
||||
if (sock_.is_open())
|
||||
sock_.close();
|
||||
return CONNECT_FAILURE;
|
||||
return false;
|
||||
}
|
||||
if(local_shared_context->ec == boost::asio::error::would_block && !r)
|
||||
{
|
||||
//timeout
|
||||
sock_.close();
|
||||
_dbg3("Failed to connect to " << adr << ":" << port << ", because of timeout (" << conn_timeout << ")");
|
||||
return CONNECT_FAILURE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ec = local_shared_context->ec;
|
||||
@@ -1296,79 +1168,11 @@ POP_WARNINGS
|
||||
_dbg3("Some problems at connect, message: " << ec.message());
|
||||
if (sock_.is_open())
|
||||
sock_.close();
|
||||
return CONNECT_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_dbg3("Connected success to " << adr << ':' << port);
|
||||
|
||||
const ssl_support_t ssl_support = new_connection_l->get_ssl_support();
|
||||
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
// Handshake
|
||||
MDEBUG("Handshaking SSL...");
|
||||
if (!new_connection_l->handshake(boost::asio::ssl::stream_base::client))
|
||||
{
|
||||
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
boost::system::error_code ignored_ec;
|
||||
sock_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
sock_.close();
|
||||
return CONNECT_NO_SSL;
|
||||
}
|
||||
MERROR("SSL handshake failed");
|
||||
if (sock_.is_open())
|
||||
sock_.close();
|
||||
return CONNECT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return CONNECT_SUCCESS;
|
||||
|
||||
CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::try_connect", CONNECT_FAILURE);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler>
|
||||
bool boosted_tcp_server<t_protocol_handler>::connect(const std::string& adr, const std::string& port, uint32_t conn_timeout, t_connection_context& conn_context, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, ssl_support) );
|
||||
connections_mutex.lock();
|
||||
connections_.insert(new_connection_l);
|
||||
MDEBUG("connections_ size now " << connections_.size());
|
||||
connections_mutex.unlock();
|
||||
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); });
|
||||
boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
boost::asio::ip::tcp::resolver resolver(io_service_);
|
||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if(iterator == end)
|
||||
{
|
||||
_erro("Failed to resolve " << adr);
|
||||
return false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port);
|
||||
boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
|
||||
|
||||
auto try_connect_result = try_connect(new_connection_l, adr, port, sock_, remote_endpoint, bind_ip, conn_timeout, ssl_support);
|
||||
if (try_connect_result == CONNECT_FAILURE)
|
||||
return false;
|
||||
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect && try_connect_result == CONNECT_NO_SSL)
|
||||
{
|
||||
// we connected, but could not connect with SSL, try without
|
||||
MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL");
|
||||
new_connection_l->disable_ssl();
|
||||
try_connect_result = try_connect(new_connection_l, adr, port, sock_, remote_endpoint, bind_ip, conn_timeout, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
|
||||
if (try_connect_result != CONNECT_SUCCESS)
|
||||
return false;
|
||||
}
|
||||
|
||||
// start adds the connection to the config object's list, so we don't need to have it locally anymore
|
||||
connections_mutex.lock();
|
||||
connections_.erase(new_connection_l);
|
||||
@@ -1381,8 +1185,7 @@ POP_WARNINGS
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(m_state != nullptr); // always set in constructor
|
||||
_erro("[sock " << new_connection_l->socket().native_handle() << "] Failed to start connection, connections_count = " << m_state->sock_count);
|
||||
_erro("[sock " << new_connection_l->socket().native_handle() << "] Failed to start connection, connections_count = " << m_sock_count);
|
||||
}
|
||||
|
||||
new_connection_l->save_dbg_log();
|
||||
@@ -1393,10 +1196,10 @@ POP_WARNINGS
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
template<class t_protocol_handler> template<class t_callback>
|
||||
bool boosted_tcp_server<t_protocol_handler>::connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeout, const t_callback &cb, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support)
|
||||
bool boosted_tcp_server<t_protocol_handler>::connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeout, const t_callback &cb, const std::string& bind_ip)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_state, m_connection_type, ssl_support) );
|
||||
connection_ptr new_connection_l(new connection<t_protocol_handler>(io_service_, m_config, m_sock_count, m_sock_number, m_pfilter, m_connection_type) );
|
||||
connections_mutex.lock();
|
||||
connections_.insert(new_connection_l);
|
||||
MDEBUG("connections_ size now " << connections_.size());
|
||||
|
||||
@@ -47,10 +47,8 @@
|
||||
#include <memory>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
#include "net/net_utils_base.h"
|
||||
#include "net/net_ssl.h"
|
||||
#include "syncobj.h"
|
||||
|
||||
namespace epee
|
||||
@@ -58,30 +56,6 @@ namespace epee
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
class connection_basic_shared_state
|
||||
{
|
||||
ssl_options_t ssl_options_;
|
||||
public:
|
||||
boost::asio::ssl::context ssl_context;
|
||||
std::atomic<long> sock_count;
|
||||
std::atomic<long> sock_number;
|
||||
|
||||
connection_basic_shared_state()
|
||||
: ssl_options_(ssl_support_t::e_ssl_support_disabled),
|
||||
ssl_context(boost::asio::ssl::context::tlsv12),
|
||||
sock_count(0),
|
||||
sock_number(0)
|
||||
{}
|
||||
|
||||
void configure_ssl(ssl_options_t src)
|
||||
{
|
||||
ssl_options_ = std::move(src);
|
||||
ssl_context = ssl_options_.create_context();
|
||||
}
|
||||
|
||||
const ssl_options_t& ssl_options() const noexcept { return ssl_options_; }
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
@@ -98,10 +72,7 @@ class connection_basic_pimpl; // PIMPL for this class
|
||||
std::string to_string(t_connection_type type);
|
||||
|
||||
class connection_basic { // not-templated base class for rapid developmet of some code parts
|
||||
// beware of removing const, net_utils::connection is sketchily doing a cast to prevent storing ptr twice
|
||||
const boost::shared_ptr<connection_basic_shared_state> m_state;
|
||||
public:
|
||||
|
||||
std::unique_ptr< connection_basic_pimpl > mI; // my Implementation
|
||||
|
||||
// moved here from orginal connecton<> - common member variables that do not depend on template in connection<>
|
||||
@@ -113,57 +84,15 @@ class connection_basic { // not-templated base class for rapid developmet of som
|
||||
/// Strand to ensure the connection's handlers are not called concurrently.
|
||||
boost::asio::io_service::strand strand_;
|
||||
/// Socket for the connection.
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
|
||||
ssl_support_t m_ssl_support;
|
||||
boost::asio::ip::tcp::socket socket_;
|
||||
|
||||
std::atomic<long> &m_ref_sock_count; // reference to external counter of existing sockets that we will ++/--
|
||||
public:
|
||||
// first counter is the ++/-- count of current sockets, the other socket_number is only-increasing ++ number generator
|
||||
connection_basic(boost::asio::ip::tcp::socket&& socket, boost::shared_ptr<connection_basic_shared_state> state, ssl_support_t ssl_support);
|
||||
connection_basic(boost::asio::io_service &io_service, boost::shared_ptr<connection_basic_shared_state> state, ssl_support_t ssl_support);
|
||||
connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number);
|
||||
|
||||
virtual ~connection_basic() noexcept(false);
|
||||
|
||||
//! \return `shared_state` object passed in construction (ptr never changes).
|
||||
connection_basic_shared_state& get_state() noexcept { return *m_state; /* verified in constructor */ }
|
||||
connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number, ssl_support_t ssl);
|
||||
|
||||
boost::asio::ip::tcp::socket& socket() { return socket_.next_layer(); }
|
||||
ssl_support_t get_ssl_support() const { return m_ssl_support; }
|
||||
void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; }
|
||||
|
||||
bool handshake(boost::asio::ssl::stream_base::handshake_type type)
|
||||
{
|
||||
//m_state != nullptr verified in constructor
|
||||
return m_state->ssl_options().handshake(socket_, type);
|
||||
}
|
||||
|
||||
template<typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some(const MutableBufferSequence &buffers, ReadHandler &&handler)
|
||||
{
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
socket_.async_read_some(buffers, std::forward<ReadHandler>(handler));
|
||||
else
|
||||
socket().async_read_some(buffers, std::forward<ReadHandler>(handler));
|
||||
}
|
||||
|
||||
template<typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some(const ConstBufferSequence &buffers, WriteHandler &&handler)
|
||||
{
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
socket_.async_write_some(buffers, std::forward<WriteHandler>(handler));
|
||||
else
|
||||
socket().async_write_some(buffers, std::forward<WriteHandler>(handler));
|
||||
}
|
||||
|
||||
template<typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write(const ConstBufferSequence &buffers, WriteHandler &&handler)
|
||||
{
|
||||
if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled)
|
||||
boost::asio::async_write(socket_, buffers, std::forward<WriteHandler>(handler));
|
||||
else
|
||||
boost::asio::async_write(socket(), buffers, std::forward<WriteHandler>(handler));
|
||||
}
|
||||
|
||||
// various handlers to be called from connection class:
|
||||
void do_send_handler_write(const void * ptr , size_t cb);
|
||||
void do_send_handler_write_from_queue(const boost::system::error_code& e, size_t cb , int q_len); // from handle_write, sending next part
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
enum class address_type : std::uint8_t
|
||||
{
|
||||
// Do not change values, this will break serialization
|
||||
invalid = 0,
|
||||
ipv4 = 1,
|
||||
ipv6 = 2,
|
||||
i2p = 3,
|
||||
tor = 4
|
||||
};
|
||||
|
||||
enum class zone : std::uint8_t
|
||||
{
|
||||
invalid = 0,
|
||||
public_ = 1, // public is keyword
|
||||
i2p = 2,
|
||||
tor = 3
|
||||
};
|
||||
|
||||
// implementations in src/net_utils_base.cpp
|
||||
|
||||
//! \return String name of zone or "invalid" on error.
|
||||
const char* zone_to_string(zone value) noexcept;
|
||||
|
||||
//! \return `zone` enum of `value` or `zone::invalid` on error.
|
||||
zone zone_from_string(boost::string_ref value) noexcept;
|
||||
} // net_utils
|
||||
} // epee
|
||||
|
||||
@@ -274,8 +274,8 @@ namespace net_utils
|
||||
reciev_machine_state m_state;
|
||||
chunked_state m_chunked_state;
|
||||
std::string m_chunked_cache;
|
||||
bool m_auto_connect;
|
||||
critical_section m_lock;
|
||||
bool m_ssl;
|
||||
|
||||
public:
|
||||
explicit http_simple_client_template()
|
||||
@@ -292,48 +292,36 @@ namespace net_utils
|
||||
, m_state()
|
||||
, m_chunked_state()
|
||||
, m_chunked_cache()
|
||||
, m_auto_connect(true)
|
||||
, m_lock()
|
||||
, m_ssl(false)
|
||||
{}
|
||||
|
||||
const std::string &get_host() const { return m_host_buff; };
|
||||
const std::string &get_port() const { return m_port; };
|
||||
|
||||
bool set_server(const std::string& address, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect)
|
||||
bool set_server(const std::string& address, boost::optional<login> user, bool ssl = false)
|
||||
{
|
||||
http::url_content parsed{};
|
||||
const bool r = parse_url(address, parsed);
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
|
||||
set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), std::move(ssl_options));
|
||||
set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), ssl);
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_server(std::string host, std::string port, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect)
|
||||
void set_server(std::string host, std::string port, boost::optional<login> user, bool ssl = false)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
disconnect();
|
||||
m_host_buff = std::move(host);
|
||||
m_port = std::move(port);
|
||||
m_auth = user ? http_client_auth{std::move(*user)} : http_client_auth{};
|
||||
m_net_client.set_ssl(std::move(ssl_options));
|
||||
}
|
||||
|
||||
void set_auto_connect(bool auto_connect)
|
||||
{
|
||||
m_auto_connect = auto_connect;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void set_connector(F connector)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
m_net_client.set_connector(std::move(connector));
|
||||
m_ssl = ssl;
|
||||
}
|
||||
|
||||
bool connect(std::chrono::milliseconds timeout)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return m_net_client.connect(m_host_buff, m_port, timeout);
|
||||
return m_net_client.connect(m_host_buff, m_port, timeout, m_ssl);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool disconnect()
|
||||
@@ -342,10 +330,10 @@ namespace net_utils
|
||||
return m_net_client.disconnect();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool is_connected(bool *ssl = NULL)
|
||||
bool is_connected()
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return m_net_client.is_connected(ssl);
|
||||
return m_net_client.is_connected();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
virtual bool handle_target_data(std::string& piece_of_transfer)
|
||||
@@ -374,11 +362,6 @@ namespace net_utils
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
if(!is_connected())
|
||||
{
|
||||
if (!m_auto_connect)
|
||||
{
|
||||
MWARNING("Auto connect attempt to " << m_host_buff << ":" << m_port << " disabled");
|
||||
return false;
|
||||
}
|
||||
MDEBUG("Reconnecting...");
|
||||
if(!connect(timeout))
|
||||
{
|
||||
@@ -456,16 +439,6 @@ namespace net_utils
|
||||
return handle_reciev(timeout);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t get_bytes_sent() const
|
||||
{
|
||||
return m_net_client.get_bytes_sent();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t get_bytes_received() const
|
||||
{
|
||||
return m_net_client.get_bytes_received();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool handle_reciev(std::chrono::milliseconds timeout)
|
||||
@@ -852,21 +825,21 @@ namespace net_utils
|
||||
const char *ptr = m_header_cache.c_str();
|
||||
CHECK_AND_ASSERT_MES(!memcmp(ptr, "HTTP/", 5), false, "Invalid first response line: " + m_header_cache);
|
||||
ptr += 5;
|
||||
CHECK_AND_ASSERT_MES(epee::misc_utils::parse::isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
unsigned long ul;
|
||||
char *end;
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul <= INT_MAX && *end =='.', false, "Invalid first response line: " + m_header_cache);
|
||||
m_response_info.m_http_ver_hi = ul;
|
||||
ptr = end + 1;
|
||||
CHECK_AND_ASSERT_MES(epee::misc_utils::parse::isdigit(*ptr), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr);
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr);
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul <= INT_MAX && isblank(*end), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr);
|
||||
m_response_info.m_http_ver_lo = ul;
|
||||
ptr = end + 1;
|
||||
while (isblank(*ptr))
|
||||
++ptr;
|
||||
CHECK_AND_ASSERT_MES(epee::misc_utils::parse::isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul >= 100 && ul <= 999 && isspace(*end), false, "Invalid first response line: " + m_header_cache);
|
||||
m_response_info.m_response_code = ul;
|
||||
|
||||
@@ -677,7 +677,7 @@ namespace net_utils
|
||||
|
||||
//add additional fields, if it is
|
||||
for(fields_list::const_iterator it = response.m_additional_fields.begin(); it!=response.m_additional_fields.end(); it++)
|
||||
buf += it->first + ": " + it->second + "\r\n";
|
||||
buf += it->first + ":" + it->second + "\r\n";
|
||||
|
||||
buf+="\r\n";
|
||||
|
||||
|
||||
@@ -58,8 +58,7 @@ namespace epee
|
||||
|
||||
bool init(std::function<void(size_t, uint8_t*)> rng, const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0",
|
||||
std::vector<std::string> access_control_origins = std::vector<std::string>(),
|
||||
boost::optional<net_utils::http::login> user = boost::none,
|
||||
net_utils::ssl_options_t ssl_options = net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
boost::optional<net_utils::http::login> user = boost::none)
|
||||
{
|
||||
|
||||
//set self as callback handler
|
||||
@@ -76,7 +75,7 @@ namespace epee
|
||||
m_net_server.get_config_object().m_user = std::move(user);
|
||||
|
||||
MGINFO("Binding on " << bind_ip << ":" << bind_port);
|
||||
bool res = m_net_server.init_server(bind_port, bind_ip, std::move(ssl_options));
|
||||
bool res = m_net_server.init_server(bind_port, bind_ip);
|
||||
if(!res)
|
||||
{
|
||||
LOG_ERROR("Failed to bind server");
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace epee
|
||||
epee::serialization::storage_entry id;
|
||||
t_param params;
|
||||
|
||||
request(): id{}, params{} {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
@@ -32,9 +30,6 @@ namespace epee
|
||||
{
|
||||
int64_t code;
|
||||
std::string message;
|
||||
|
||||
error(): code(0) {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(code)
|
||||
KV_SERIALIZE(message)
|
||||
@@ -60,9 +55,6 @@ namespace epee
|
||||
t_param result;
|
||||
epee::serialization::storage_entry id;
|
||||
t_error error;
|
||||
|
||||
response(): result{}, id(), error{} {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
@@ -77,9 +69,6 @@ namespace epee
|
||||
std::string jsonrpc;
|
||||
t_param result;
|
||||
epee::serialization::storage_entry id;
|
||||
|
||||
response(): result{}, id{} {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
@@ -93,9 +82,6 @@ namespace epee
|
||||
std::string jsonrpc;
|
||||
t_error error;
|
||||
epee::serialization::storage_entry id;
|
||||
|
||||
response(): error{}, id{} {}
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
m_pservice_endpoint(psnd_hndlr),
|
||||
m_config(config),
|
||||
m_connection_context(conn_context),
|
||||
m_cache_in_buffer(4 * 1024),
|
||||
m_cache_in_buffer(256 * 1024),
|
||||
m_state(stream_state_head)
|
||||
{
|
||||
m_close_called = 0;
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
struct ssl_authentication_t;
|
||||
class ssl_options_t;
|
||||
}
|
||||
}
|
||||
@@ -33,19 +33,13 @@
|
||||
//#include <Ws2tcpip.h>
|
||||
#include <string>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <functional>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "net/net_ssl.h"
|
||||
#include "misc_language.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
@@ -60,22 +54,9 @@ namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
struct direct_connect
|
||||
{
|
||||
boost::unique_future<boost::asio::ip::tcp::socket>
|
||||
operator()(const std::string& addr, const std::string& port, boost::asio::steady_timer&) const;
|
||||
};
|
||||
|
||||
|
||||
class blocked_mode_client
|
||||
{
|
||||
enum try_connect_result_t
|
||||
{
|
||||
CONNECT_SUCCESS,
|
||||
CONNECT_FAILURE,
|
||||
CONNECT_NO_SSL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct handler_obj
|
||||
@@ -96,40 +77,31 @@ namespace net_utils
|
||||
ref_bytes_transferred = bytes_transferred;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
inline
|
||||
blocked_mode_client() :
|
||||
m_io_service(),
|
||||
m_ctx(boost::asio::ssl::context::tlsv12),
|
||||
m_connector(direct_connect{}),
|
||||
m_ssl_socket(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx)),
|
||||
m_ssl_options(epee::net_utils::ssl_support_t::e_ssl_support_autodetect),
|
||||
m_initialized(true),
|
||||
m_connected(false),
|
||||
m_deadline(m_io_service),
|
||||
m_shutdowned(0),
|
||||
m_bytes_sent(0),
|
||||
m_bytes_received(0)
|
||||
blocked_mode_client():m_initialized(false),
|
||||
m_connected(false),
|
||||
m_deadline(m_io_service),
|
||||
m_shutdowned(0),
|
||||
m_ssl(false),
|
||||
m_ctx(boost::asio::ssl::context::sslv23),
|
||||
m_ssl_socket(m_io_service,m_ctx)
|
||||
{
|
||||
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
|
||||
// No deadline is required until the first socket operation is started. We
|
||||
// set the deadline to positive infinity so that the actor takes no action
|
||||
// until a specific deadline is set.
|
||||
m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
|
||||
// Start the persistent actor that checks for deadline expiry.
|
||||
check_deadline();
|
||||
|
||||
}
|
||||
|
||||
/*! The first/second parameters are host/port respectively. The third
|
||||
parameter is for setting the timeout callback - the timer is
|
||||
already set by the caller, the callee only needs to set the
|
||||
behavior.
|
||||
|
||||
Additional asynchronous operations should be queued using the
|
||||
`io_service` from the timer. The implementation should assume
|
||||
multi-threaded I/O processing.
|
||||
|
||||
If the callee cannot start an asynchronous operation, an exception
|
||||
should be thrown to signal an immediate failure.
|
||||
|
||||
The return value is a future to a connected socket. Asynchronous
|
||||
failures should use the `set_exception` method. */
|
||||
using connect_func = boost::unique_future<boost::asio::ip::tcp::socket>(const std::string&, const std::string&, boost::asio::steady_timer&);
|
||||
|
||||
inline
|
||||
~blocked_mode_client()
|
||||
{
|
||||
@@ -138,100 +110,86 @@ namespace net_utils
|
||||
catch(...) { /* ignore */ }
|
||||
}
|
||||
|
||||
inline void set_ssl(ssl_options_t ssl_options)
|
||||
{
|
||||
if (ssl_options)
|
||||
m_ctx = ssl_options.create_context();
|
||||
else
|
||||
m_ctx = boost::asio::ssl::context(boost::asio::ssl::context::tlsv12);
|
||||
m_ssl_options = std::move(ssl_options);
|
||||
}
|
||||
|
||||
inline
|
||||
bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout)
|
||||
bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0")
|
||||
{
|
||||
return connect(addr, std::to_string(port), timeout);
|
||||
return connect(addr, std::to_string(port), timeout, ssl, bind_ip);
|
||||
}
|
||||
|
||||
inline
|
||||
try_connect_result_t try_connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, epee::net_utils::ssl_support_t ssl_support)
|
||||
bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0")
|
||||
{
|
||||
m_deadline.expires_from_now(timeout);
|
||||
boost::unique_future<boost::asio::ip::tcp::socket> connection = m_connector(addr, port, m_deadline);
|
||||
for (;;)
|
||||
{
|
||||
m_io_service.reset();
|
||||
m_io_service.run_one();
|
||||
m_connected = false;
|
||||
m_ssl = ssl;
|
||||
try
|
||||
{
|
||||
m_ssl_socket.next_layer().close();
|
||||
|
||||
if (connection.is_ready())
|
||||
break;
|
||||
// Set SSL options
|
||||
// disable sslv2
|
||||
m_ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2);
|
||||
m_ctx.set_default_verify_paths();
|
||||
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(m_io_service);
|
||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if(iterator == end)
|
||||
{
|
||||
LOG_ERROR("Failed to resolve " << addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ssl_socket->next_layer() = connection.get();
|
||||
m_deadline.cancel();
|
||||
if (m_ssl_socket->next_layer().is_open())
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port);
|
||||
boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
|
||||
|
||||
|
||||
m_ssl_socket.next_layer().open(remote_endpoint.protocol());
|
||||
if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" )
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(addr.c_str()), 0);
|
||||
m_ssl_socket.next_layer().bind(local_endpoint);
|
||||
}
|
||||
|
||||
|
||||
m_deadline.expires_from_now(timeout);
|
||||
|
||||
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
m_ssl_socket.next_layer().async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1);
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
if (!ec && m_ssl_socket.next_layer().is_open())
|
||||
{
|
||||
m_connected = true;
|
||||
m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
// SSL Options
|
||||
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr))
|
||||
{
|
||||
if (ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
boost::system::error_code ignored_ec;
|
||||
m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
m_ssl_socket->next_layer().close();
|
||||
m_connected = false;
|
||||
return CONNECT_NO_SSL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MWARNING("Failed to establish SSL connection");
|
||||
m_connected = false;
|
||||
return CONNECT_FAILURE;
|
||||
}
|
||||
}
|
||||
m_ssl_options.support = ssl_support_t::e_ssl_support_enabled;
|
||||
if(m_ssl) {
|
||||
// Disable verification of host certificate
|
||||
m_ssl_socket.set_verify_mode(boost::asio::ssl::verify_peer);
|
||||
// Handshake
|
||||
m_ssl_socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
m_ssl_socket.handshake(boost::asio::ssl::stream_base::client);
|
||||
}
|
||||
return CONNECT_SUCCESS;
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
MWARNING("Some problems at connect, expected open socket");
|
||||
return CONNECT_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline
|
||||
bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout)
|
||||
{
|
||||
m_connected = false;
|
||||
try
|
||||
{
|
||||
m_ssl_socket->next_layer().close();
|
||||
|
||||
// Set SSL options
|
||||
// disable sslv2
|
||||
m_ssl_socket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, m_ctx));
|
||||
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
|
||||
try_connect_result_t try_connect_result = try_connect(addr, port, timeout, m_ssl_options.support);
|
||||
if (try_connect_result == CONNECT_FAILURE)
|
||||
MWARNING("Some problems at connect, message: " << ec.message());
|
||||
return false;
|
||||
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
m_ssl_options.support = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
|
||||
if (try_connect_result == CONNECT_NO_SSL)
|
||||
{
|
||||
MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL");
|
||||
m_ssl_options.support = epee::net_utils::ssl_support_t::e_ssl_support_disabled;
|
||||
if (try_connect(addr, port, timeout, m_ssl_options.support) != CONNECT_SUCCESS)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
@@ -246,11 +204,6 @@ namespace net_utils
|
||||
|
||||
return true;
|
||||
}
|
||||
//! Change the connection routine (proxy, etc.)
|
||||
void set_connector(std::function<connect_func> connector)
|
||||
{
|
||||
m_connector = std::move(connector);
|
||||
}
|
||||
|
||||
inline
|
||||
bool disconnect()
|
||||
@@ -260,11 +213,12 @@ namespace net_utils
|
||||
if(m_connected)
|
||||
{
|
||||
m_connected = false;
|
||||
if(m_ssl_options)
|
||||
if(m_ssl)
|
||||
shutdown_ssl();
|
||||
m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
}
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& /*er*/)
|
||||
{
|
||||
//LOG_ERROR("Some problems at disconnect, message: " << er.what());
|
||||
@@ -303,7 +257,6 @@ namespace net_utils
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.reset();
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
@@ -315,7 +268,6 @@ namespace net_utils
|
||||
}else
|
||||
{
|
||||
m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
m_bytes_sent += buff.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +324,6 @@ namespace net_utils
|
||||
}else
|
||||
{
|
||||
m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
m_bytes_sent += sz;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,13 +342,9 @@ namespace net_utils
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_connected(bool *ssl = NULL)
|
||||
bool is_connected()
|
||||
{
|
||||
if (!m_connected || !m_ssl_socket->next_layer().is_open())
|
||||
return false;
|
||||
if (ssl)
|
||||
*ssl = m_ssl_options.support == ssl_support_t::e_ssl_support_enabled;
|
||||
return true;
|
||||
return m_connected && m_ssl_socket.next_layer().is_open();
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -428,15 +375,13 @@ namespace net_utils
|
||||
|
||||
handler_obj hndlr(ec, bytes_transfered);
|
||||
|
||||
static const size_t max_size = 16384;
|
||||
buff.resize(max_size);
|
||||
char local_buff[10000] = {0};
|
||||
|
||||
async_read(&buff[0], max_size, boost::asio::transfer_at_least(1), hndlr);
|
||||
async_read(local_buff, sizeof(local_buff), boost::asio::transfer_at_least(1), hndlr);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block && !boost::interprocess::ipcdetail::atomic_read32(&m_shutdowned))
|
||||
{
|
||||
m_io_service.reset();
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
@@ -448,7 +393,6 @@ namespace net_utils
|
||||
{
|
||||
MTRACE("Connection err_code eof.");
|
||||
//connection closed there, empty
|
||||
buff.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -464,8 +408,7 @@ namespace net_utils
|
||||
/*if(!bytes_transfered)
|
||||
return false;*/
|
||||
|
||||
m_bytes_received += bytes_transfered;
|
||||
buff.resize(bytes_transfered);
|
||||
buff.assign(local_buff, bytes_transfered);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -533,7 +476,6 @@ namespace net_utils
|
||||
m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
}
|
||||
|
||||
m_bytes_received += bytes_transfered;
|
||||
if(bytes_transfered != buff.size())
|
||||
{
|
||||
LOG_ERROR("Transferred mismatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size());
|
||||
@@ -564,15 +506,15 @@ namespace net_utils
|
||||
{
|
||||
m_deadline.cancel();
|
||||
boost::system::error_code ec;
|
||||
if(m_ssl_options.support != ssl_support_t::e_ssl_support_disabled)
|
||||
if(m_ssl)
|
||||
shutdown_ssl();
|
||||
m_ssl_socket->next_layer().cancel(ec);
|
||||
m_ssl_socket.next_layer().cancel(ec);
|
||||
if(ec)
|
||||
MDEBUG("Problems at cancel: " << ec.message());
|
||||
m_ssl_socket->next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
if(ec)
|
||||
MDEBUG("Problems at shutdown: " << ec.message());
|
||||
m_ssl_socket->next_layer().close(ec);
|
||||
m_ssl_socket.next_layer().close(ec);
|
||||
if(ec)
|
||||
MDEBUG("Problems at close: " << ec.message());
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_shutdowned, 1);
|
||||
@@ -580,6 +522,10 @@ namespace net_utils
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_connected(bool connected)
|
||||
{
|
||||
m_connected = connected;
|
||||
}
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return m_io_service;
|
||||
@@ -587,19 +533,9 @@ namespace net_utils
|
||||
|
||||
boost::asio::ip::tcp::socket& get_socket()
|
||||
{
|
||||
return m_ssl_socket->next_layer();
|
||||
return m_ssl_socket.next_layer();
|
||||
}
|
||||
|
||||
uint64_t get_bytes_sent() const
|
||||
{
|
||||
return m_bytes_sent;
|
||||
}
|
||||
|
||||
uint64_t get_bytes_received() const
|
||||
{
|
||||
return m_bytes_received;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void check_deadline()
|
||||
@@ -614,7 +550,7 @@ namespace net_utils
|
||||
// connect(), read_line() or write_line() functions to return.
|
||||
LOG_PRINT_L3("Timed out socket");
|
||||
m_connected = false;
|
||||
m_ssl_socket->next_layer().close();
|
||||
m_ssl_socket.next_layer().close();
|
||||
|
||||
// There is no longer an active deadline. The expiry is set to positive
|
||||
// infinity so that the actor takes no action until a new deadline is set.
|
||||
@@ -629,10 +565,9 @@ namespace net_utils
|
||||
// ssl socket shutdown blocks if server doesn't respond. We close after 2 secs
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
m_deadline.expires_from_now(std::chrono::milliseconds(2000));
|
||||
m_ssl_socket->async_shutdown(boost::lambda::var(ec) = boost::lambda::_1);
|
||||
m_ssl_socket.async_shutdown(boost::lambda::var(ec) = boost::lambda::_1);
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.reset();
|
||||
m_io_service.run_one();
|
||||
}
|
||||
// Ignore "short read" error
|
||||
@@ -651,42 +586,39 @@ namespace net_utils
|
||||
bool write(const void* data, size_t sz, boost::system::error_code& ec)
|
||||
{
|
||||
bool success;
|
||||
if(m_ssl_options.support == ssl_support_t::e_ssl_support_enabled)
|
||||
success = boost::asio::write(*m_ssl_socket, boost::asio::buffer(data, sz), ec);
|
||||
if(m_ssl)
|
||||
success = boost::asio::write(m_ssl_socket, boost::asio::buffer(data, sz), ec);
|
||||
else
|
||||
success = boost::asio::write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), ec);
|
||||
success = boost::asio::write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), ec);
|
||||
return success;
|
||||
}
|
||||
|
||||
void async_write(const void* data, size_t sz, boost::system::error_code& ec)
|
||||
{
|
||||
if(m_ssl_options.support == ssl_support_t::e_ssl_support_enabled)
|
||||
boost::asio::async_write(*m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
if(m_ssl)
|
||||
boost::asio::async_write(m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
else
|
||||
boost::asio::async_write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
boost::asio::async_write(m_ssl_socket.next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
}
|
||||
|
||||
void async_read(char* buff, size_t sz, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj& hndlr)
|
||||
{
|
||||
if(m_ssl_options.support != ssl_support_t::e_ssl_support_enabled)
|
||||
boost::asio::async_read(m_ssl_socket->next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
|
||||
if(!m_ssl)
|
||||
boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
|
||||
else
|
||||
boost::asio::async_read(*m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
|
||||
boost::asio::async_read(m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
boost::asio::io_service m_io_service;
|
||||
boost::asio::ssl::context m_ctx;
|
||||
std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> m_ssl_socket;
|
||||
std::function<connect_func> m_connector;
|
||||
ssl_options_t m_ssl_options;
|
||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_ssl_socket;
|
||||
bool m_ssl;
|
||||
bool m_initialized;
|
||||
bool m_connected;
|
||||
boost::asio::steady_timer m_deadline;
|
||||
volatile uint32_t m_shutdowned;
|
||||
std::atomic<uint64_t> m_bytes_sent;
|
||||
std::atomic<uint64_t> m_bytes_received;
|
||||
};
|
||||
|
||||
|
||||
@@ -790,7 +722,7 @@ namespace net_utils
|
||||
// asynchronous operations are cancelled. This allows the blocked
|
||||
// connect(), read_line() or write_line() functions to return.
|
||||
LOG_PRINT_L3("Timed out socket");
|
||||
m_ssl_socket->next_layer().close();
|
||||
m_ssl_socket.next_layer().close();
|
||||
|
||||
// There is no longer an active deadline. The expiry is set to positive
|
||||
// infinity so that the actor takes no action until a new deadline is set.
|
||||
@@ -803,4 +735,3 @@ namespace net_utils
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef _NET_SSL_H
|
||||
#define _NET_SSL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#define SSL_FINGERPRINT_SIZE 32
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
enum class ssl_support_t: uint8_t {
|
||||
e_ssl_support_disabled,
|
||||
e_ssl_support_enabled,
|
||||
e_ssl_support_autodetect,
|
||||
};
|
||||
|
||||
enum class ssl_verification_t : uint8_t
|
||||
{
|
||||
none = 0, //!< Do not verify peer.
|
||||
system_ca, //!< Verify peer via system ca only (do not inspect user certificates)
|
||||
user_certificates,//!< Verify peer via specific (non-chain) certificate(s) only.
|
||||
user_ca //!< Verify peer via specific (possibly chain) certificate(s) only.
|
||||
};
|
||||
|
||||
struct ssl_authentication_t
|
||||
{
|
||||
std::string private_key_path; //!< Private key used for authentication
|
||||
std::string certificate_path; //!< Certificate used for authentication to peer.
|
||||
|
||||
//! Load `private_key_path` and `certificate_path` into `ssl_context`.
|
||||
void use_ssl_certificate(boost::asio::ssl::context &ssl_context) const;
|
||||
};
|
||||
|
||||
/*!
|
||||
\note `verification != disabled && support == disabled` is currently
|
||||
"allowed" via public interface but obviously invalid configuation.
|
||||
*/
|
||||
class ssl_options_t
|
||||
{
|
||||
// force sorted behavior in private
|
||||
std::vector<std::vector<std::uint8_t>> fingerprints_;
|
||||
|
||||
public:
|
||||
std::string ca_path;
|
||||
ssl_authentication_t auth;
|
||||
ssl_support_t support;
|
||||
ssl_verification_t verification;
|
||||
|
||||
//! Verification is set to system ca unless SSL is disabled.
|
||||
ssl_options_t(ssl_support_t support)
|
||||
: fingerprints_(),
|
||||
ca_path(),
|
||||
auth(),
|
||||
support(support),
|
||||
verification(support == ssl_support_t::e_ssl_support_disabled ? ssl_verification_t::none : ssl_verification_t::system_ca)
|
||||
{}
|
||||
|
||||
//! Provide user fingerprints and/or ca path. Enables SSL and user_certificate verification
|
||||
ssl_options_t(std::vector<std::vector<std::uint8_t>> fingerprints, std::string ca_path);
|
||||
|
||||
ssl_options_t(const ssl_options_t&) = default;
|
||||
ssl_options_t(ssl_options_t&&) = default;
|
||||
|
||||
ssl_options_t& operator=(const ssl_options_t&) = default;
|
||||
ssl_options_t& operator=(ssl_options_t&&) = default;
|
||||
|
||||
//! \return False iff ssl is disabled, otherwise true.
|
||||
explicit operator bool() const noexcept { return support != ssl_support_t::e_ssl_support_disabled; }
|
||||
|
||||
//! \retrurn True if `host` can be verified using `this` configuration WITHOUT system "root" CAs.
|
||||
bool has_strong_verification(boost::string_ref host) const noexcept;
|
||||
|
||||
//! Search against internal fingerprints. Always false if `behavior() != user_certificate_check`.
|
||||
bool has_fingerprint(boost::asio::ssl::verify_context &ctx) const;
|
||||
|
||||
boost::asio::ssl::context create_context() const;
|
||||
|
||||
/*! \note If `this->support == autodetect && this->verification != none`,
|
||||
then the handshake will not fail when peer verification fails. The
|
||||
assumption is that a re-connect will be attempted, so a warning is
|
||||
logged instead of failure.
|
||||
|
||||
\note It is strongly encouraged that clients using `system_ca`
|
||||
verification provide a non-empty `host` for rfc2818 verification.
|
||||
|
||||
\param socket Used in SSL handshake and verification
|
||||
\param type Client or server
|
||||
\param host This parameter is only used when
|
||||
`type == client && !host.empty()`. The value is sent to the server for
|
||||
situations where multiple hostnames are being handled by a server. If
|
||||
`verification == system_ca` the client also does a rfc2818 check to
|
||||
ensure that the server certificate is to the provided hostname.
|
||||
|
||||
\return True if the SSL handshake completes with peer verification
|
||||
settings. */
|
||||
bool handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const std::string& host = {}) const;
|
||||
};
|
||||
|
||||
// https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification
|
||||
constexpr size_t get_ssl_magic_size() { return 9; }
|
||||
bool is_ssl(const unsigned char *data, size_t len);
|
||||
bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s);
|
||||
|
||||
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
|
||||
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //_NET_SSL_H
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include "enums.h"
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
@@ -44,18 +43,6 @@
|
||||
#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION >= 107000
|
||||
#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
|
||||
#else
|
||||
#define GET_IO_SERVICE(s) ((s).get_io_service())
|
||||
#endif
|
||||
|
||||
namespace net
|
||||
{
|
||||
class tor_address;
|
||||
class i2p_address;
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
@@ -66,10 +53,6 @@ namespace net_utils
|
||||
uint16_t m_port;
|
||||
|
||||
public:
|
||||
constexpr ipv4_network_address() noexcept
|
||||
: ipv4_network_address(0, 0)
|
||||
{}
|
||||
|
||||
constexpr ipv4_network_address(uint32_t ip, uint16_t port) noexcept
|
||||
: m_ip(ip), m_port(port) {}
|
||||
|
||||
@@ -84,10 +67,9 @@ namespace net_utils
|
||||
std::string host_str() const;
|
||||
bool is_loopback() const;
|
||||
bool is_local() const;
|
||||
static constexpr address_type get_type_id() noexcept { return address_type::ipv4; }
|
||||
static constexpr zone get_zone() noexcept { return zone::public_; }
|
||||
static constexpr bool is_blockable() noexcept { return true; }
|
||||
static constexpr uint8_t get_type_id() noexcept { return ID; }
|
||||
|
||||
static const uint8_t ID = 1;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(m_ip)
|
||||
KV_SERIALIZE(m_port)
|
||||
@@ -121,9 +103,7 @@ namespace net_utils
|
||||
virtual std::string host_str() const = 0;
|
||||
virtual bool is_loopback() const = 0;
|
||||
virtual bool is_local() const = 0;
|
||||
virtual address_type get_type_id() const = 0;
|
||||
virtual zone get_zone() const = 0;
|
||||
virtual bool is_blockable() const = 0;
|
||||
virtual uint8_t get_type_id() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -151,9 +131,7 @@ namespace net_utils
|
||||
virtual std::string host_str() const override { return value.host_str(); }
|
||||
virtual bool is_loopback() const override { return value.is_loopback(); }
|
||||
virtual bool is_local() const override { return value.is_local(); }
|
||||
virtual address_type get_type_id() const override { return value.get_type_id(); }
|
||||
virtual zone get_zone() const override { return value.get_zone(); }
|
||||
virtual bool is_blockable() const override { return value.is_blockable(); }
|
||||
virtual uint8_t get_type_id() const override { return value.get_type_id(); }
|
||||
};
|
||||
|
||||
std::shared_ptr<interface> self;
|
||||
@@ -168,23 +146,6 @@ namespace net_utils
|
||||
throw std::bad_cast{};
|
||||
return static_cast<implementation<Type_>*>(self_)->value;
|
||||
}
|
||||
|
||||
template<typename T, typename t_storage>
|
||||
bool serialize_addr(std::false_type, t_storage& stg, typename t_storage::hsection hparent)
|
||||
{
|
||||
T addr{};
|
||||
if (!epee::serialization::selector<false>::serialize(addr, stg, hparent, "addr"))
|
||||
return false;
|
||||
*this = std::move(addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename t_storage>
|
||||
bool serialize_addr(std::true_type, t_storage& stg, typename t_storage::hsection hparent) const
|
||||
{
|
||||
return epee::serialization::selector<true>::serialize(as<T>(), stg, hparent, "addr");
|
||||
}
|
||||
|
||||
public:
|
||||
network_address() : self(nullptr) {}
|
||||
template<typename T>
|
||||
@@ -197,34 +158,43 @@ namespace net_utils
|
||||
std::string host_str() const { return self ? self->host_str() : "<none>"; }
|
||||
bool is_loopback() const { return self ? self->is_loopback() : false; }
|
||||
bool is_local() const { return self ? self->is_local() : false; }
|
||||
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
|
||||
zone get_zone() const { return self ? self->get_zone() : zone::invalid; }
|
||||
bool is_blockable() const { return self ? self->is_blockable() : false; }
|
||||
uint8_t get_type_id() const { return self ? self->get_type_id() : 0; }
|
||||
template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
// need to `#include "net/[i2p|tor]_address.h"` when serializing `network_address`
|
||||
static constexpr std::integral_constant<bool, is_store> is_store_{};
|
||||
|
||||
std::uint8_t type = std::uint8_t(is_store ? this_ref.get_type_id() : address_type::invalid);
|
||||
uint8_t type = is_store ? this_ref.get_type_id() : 0;
|
||||
if (!epee::serialization::selector<is_store>::serialize(type, stg, hparent_section, "type"))
|
||||
return false;
|
||||
|
||||
switch (address_type(type))
|
||||
switch (type)
|
||||
{
|
||||
case address_type::ipv4:
|
||||
return this_ref.template serialize_addr<ipv4_network_address>(is_store_, stg, hparent_section);
|
||||
case address_type::tor:
|
||||
return this_ref.template serialize_addr<net::tor_address>(is_store_, stg, hparent_section);
|
||||
case address_type::i2p:
|
||||
return this_ref.template serialize_addr<net::i2p_address>(is_store_, stg, hparent_section);
|
||||
case address_type::invalid:
|
||||
default:
|
||||
case ipv4_network_address::ID:
|
||||
{
|
||||
if (!is_store)
|
||||
{
|
||||
const_cast<network_address&>(this_ref) = ipv4_network_address{0, 0};
|
||||
auto &addr = this_ref.template as_mutable<ipv4_network_address>();
|
||||
if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "addr"))
|
||||
MDEBUG("Found as addr: " << this_ref.str());
|
||||
else if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "template as<ipv4_network_address>()"))
|
||||
MDEBUG("Found as template as<ipv4_network_address>(): " << this_ref.str());
|
||||
else if (epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "template as_mutable<ipv4_network_address>()"))
|
||||
MDEBUG("Found as template as_mutable<ipv4_network_address>(): " << this_ref.str());
|
||||
else
|
||||
{
|
||||
MWARNING("Address not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &addr = this_ref.template as_mutable<ipv4_network_address>();
|
||||
if (!epee::serialization::selector<is_store>::serialize(addr, stg, hparent_section, "addr"))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: MERROR("Unsupported network address type: " << (unsigned)type); return false;
|
||||
}
|
||||
|
||||
MERROR("Unsupported network address type: " << (unsigned)type);
|
||||
return false;
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
@@ -241,6 +211,8 @@ namespace net_utils
|
||||
inline bool operator>=(const network_address& lhs, const network_address& rhs)
|
||||
{ return !lhs.less(rhs); }
|
||||
|
||||
bool create_network_address(network_address &address, const std::string &string, uint16_t default_port = 0);
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
@@ -250,63 +222,54 @@ namespace net_utils
|
||||
const network_address m_remote_address;
|
||||
const bool m_is_income;
|
||||
const time_t m_started;
|
||||
const time_t m_ssl;
|
||||
time_t m_last_recv;
|
||||
time_t m_last_send;
|
||||
uint64_t m_recv_cnt;
|
||||
uint64_t m_send_cnt;
|
||||
double m_current_speed_down;
|
||||
double m_current_speed_up;
|
||||
double m_max_speed_down;
|
||||
double m_max_speed_up;
|
||||
|
||||
connection_context_base(boost::uuids::uuid connection_id,
|
||||
const network_address &remote_address, bool is_income, bool ssl,
|
||||
const network_address &remote_address, bool is_income,
|
||||
time_t last_recv = 0, time_t last_send = 0,
|
||||
uint64_t recv_cnt = 0, uint64_t send_cnt = 0):
|
||||
m_connection_id(connection_id),
|
||||
m_remote_address(remote_address),
|
||||
m_is_income(is_income),
|
||||
m_started(time(NULL)),
|
||||
m_ssl(ssl),
|
||||
m_last_recv(last_recv),
|
||||
m_last_send(last_send),
|
||||
m_recv_cnt(recv_cnt),
|
||||
m_send_cnt(send_cnt),
|
||||
m_current_speed_down(0),
|
||||
m_current_speed_up(0),
|
||||
m_max_speed_down(0),
|
||||
m_max_speed_up(0)
|
||||
m_current_speed_up(0)
|
||||
{}
|
||||
|
||||
connection_context_base(): m_connection_id(),
|
||||
m_remote_address(),
|
||||
m_remote_address(ipv4_network_address{0,0}),
|
||||
m_is_income(false),
|
||||
m_started(time(NULL)),
|
||||
m_ssl(false),
|
||||
m_last_recv(0),
|
||||
m_last_send(0),
|
||||
m_recv_cnt(0),
|
||||
m_send_cnt(0),
|
||||
m_current_speed_down(0),
|
||||
m_current_speed_up(0),
|
||||
m_max_speed_down(0),
|
||||
m_max_speed_up(0)
|
||||
m_current_speed_up(0)
|
||||
{}
|
||||
|
||||
connection_context_base& operator=(const connection_context_base& a)
|
||||
{
|
||||
set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl);
|
||||
set_details(a.m_connection_id, a.m_remote_address, a.m_is_income);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
template<class t_protocol_handler>
|
||||
friend class connection;
|
||||
void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income, bool ssl)
|
||||
void set_details(boost::uuids::uuid connection_id, const network_address &remote_address, bool is_income)
|
||||
{
|
||||
this->~connection_context_base();
|
||||
new(this) connection_context_base(connection_id, remote_address, is_income, ssl);
|
||||
new(this) connection_context_base(connection_id, remote_address, is_income);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#ifndef INCLUDED_throttle_detail_hpp
|
||||
#define INCLUDED_throttle_detail_hpp
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include "network_throttle.hpp"
|
||||
|
||||
namespace epee
|
||||
@@ -62,12 +61,10 @@ class network_throttle : public i_network_throttle {
|
||||
network_time_seconds m_slot_size; // the size of one slot. TODO: now hardcoded for 1 second e.g. in time_to_slot()
|
||||
// TODO for big window size, for performance better the substract on change of m_last_sample_time instead of recalculating average of eg >100 elements
|
||||
|
||||
boost::circular_buffer< packet_info > m_history; // the history of bw usage
|
||||
std::vector< packet_info > m_history; // the history of bw usage
|
||||
network_time_seconds m_last_sample_time; // time of last history[0] - so we know when to rotate the buffer
|
||||
network_time_seconds m_start_time; // when we were created
|
||||
bool m_any_packet_yet; // did we yet got any packet to count
|
||||
uint64_t m_total_packets;
|
||||
uint64_t m_total_bytes;
|
||||
|
||||
std::string m_name; // my name for debug and logs
|
||||
std::string m_nameshort; // my name for debug and logs (used in log file name)
|
||||
@@ -97,7 +94,6 @@ class network_throttle : public i_network_throttle {
|
||||
virtual size_t get_recommended_size_of_planned_transport() const; ///< what should be the size (bytes) of next data block to be transported
|
||||
virtual size_t get_recommended_size_of_planned_transport_window(double force_window) const; ///< ditto, but for given windows time frame
|
||||
virtual double get_current_speed() const;
|
||||
virtual void get_stats(uint64_t &total_packets, uint64_t &total_bytes) const;
|
||||
|
||||
private:
|
||||
virtual network_time_seconds time_to_slot(network_time_seconds t) const { return std::floor( t ); } // convert exact time eg 13.7 to rounded time for slot number in history 13
|
||||
|
||||
@@ -152,8 +152,7 @@ class i_network_throttle {
|
||||
virtual size_t get_recommended_size_of_planned_transport() const =0; // what should be the recommended limit of data size that we can transport over current network_throttle in near future
|
||||
|
||||
virtual double get_time_seconds() const =0; // a timer
|
||||
virtual void logger_handle_net(const std::string &filename, double time, size_t size)=0;
|
||||
virtual void get_stats(uint64_t &total_packets, uint64_t &total_bytes) const =0;
|
||||
virtual void logger_handle_net(const std::string &filename, double time, size_t size)=0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Adapted from source by AShelly:
|
||||
// Copyright (c) 2011 ashelly.myopenid.com, licenced under the MIT licence
|
||||
// https://stackoverflow.com/questions/5527437/rolling-median-in-c-turlach-implementation
|
||||
// https://stackoverflow.com/questions/1309263/rolling-median-algorithm-in-c
|
||||
// https://ideone.com/XPbl6
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace misc_utils
|
||||
{
|
||||
|
||||
template<typename Item>
|
||||
struct rolling_median_t
|
||||
{
|
||||
private:
|
||||
Item* data; //circular queue of values
|
||||
int* pos; //index into `heap` for each value
|
||||
int* heap; //max/median/min heap holding indexes into `data`.
|
||||
int N; //allocated size.
|
||||
int idx; //position in circular queue
|
||||
int minCt; //count of items in min heap
|
||||
int maxCt; //count of items in max heap
|
||||
int sz; //count of items in heap
|
||||
|
||||
private:
|
||||
|
||||
//returns true if heap[i] < heap[j]
|
||||
bool mmless(int i, int j) const
|
||||
{
|
||||
return data[heap[i]] < data[heap[j]];
|
||||
}
|
||||
|
||||
//swaps items i&j in heap, maintains indexes
|
||||
bool mmexchange(int i, int j)
|
||||
{
|
||||
const int t = heap[i];
|
||||
heap[i] = heap[j];
|
||||
heap[j] = t;
|
||||
pos[heap[i]] = i;
|
||||
pos[heap[j]] = j;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//swaps items i&j if i<j; returns true if swapped
|
||||
bool mmCmpExch(int i, int j)
|
||||
{
|
||||
return mmless(i, j) && mmexchange(i, j);
|
||||
}
|
||||
|
||||
//maintains minheap property for all items below i.
|
||||
void minSortDown(int i)
|
||||
{
|
||||
for (i *= 2; i <= minCt; i *= 2)
|
||||
{
|
||||
if (i < minCt && mmless(i + 1, i))
|
||||
++i;
|
||||
if (!mmCmpExch(i, i / 2))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//maintains maxheap property for all items below i. (negative indexes)
|
||||
void maxSortDown(int i)
|
||||
{
|
||||
for (i *= 2; i >= -maxCt; i *= 2)
|
||||
{
|
||||
if (i > -maxCt && mmless(i, i - 1))
|
||||
--i;
|
||||
if (!mmCmpExch(i / 2, i))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//maintains minheap property for all items above i, including median
|
||||
//returns true if median changed
|
||||
bool minSortUp(int i)
|
||||
{
|
||||
while (i > 0 && mmCmpExch(i, i / 2))
|
||||
i /= 2;
|
||||
return i == 0;
|
||||
}
|
||||
|
||||
//maintains maxheap property for all items above i, including median
|
||||
//returns true if median changed
|
||||
bool maxSortUp(int i)
|
||||
{
|
||||
while (i < 0 && mmCmpExch(i / 2, i))
|
||||
i /= 2;
|
||||
return i == 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
rolling_median_t &operator=(const rolling_median_t&) = delete;
|
||||
rolling_median_t(const rolling_median_t&) = delete;
|
||||
|
||||
public:
|
||||
//creates new rolling_median_t: to calculate `nItems` running median.
|
||||
rolling_median_t(size_t N): N(N)
|
||||
{
|
||||
int size = N * (sizeof(Item) + sizeof(int) * 2);
|
||||
data = (Item*)malloc(size);
|
||||
pos = (int*) (data + N);
|
||||
heap = pos + N + (N / 2); //points to middle of storage.
|
||||
clear();
|
||||
}
|
||||
|
||||
rolling_median_t(rolling_median_t &&m)
|
||||
{
|
||||
free(data);
|
||||
memcpy(this, &m, sizeof(rolling_median_t));
|
||||
m.data = NULL;
|
||||
}
|
||||
rolling_median_t &operator=(rolling_median_t &&m)
|
||||
{
|
||||
free(data);
|
||||
memcpy(this, &m, sizeof(rolling_median_t));
|
||||
m.data = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~rolling_median_t()
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
idx = 0;
|
||||
minCt = 0;
|
||||
maxCt = 0;
|
||||
sz = 0;
|
||||
int nItems = N;
|
||||
while (nItems--) //set up initial heap fill pattern: median,max,min,max,...
|
||||
{
|
||||
pos[nItems] = ((nItems + 1) / 2) * ((nItems & 1) ? -1 : 1);
|
||||
heap[pos[nItems]] = nItems;
|
||||
}
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
//Inserts item, maintains median in O(lg nItems)
|
||||
void insert(Item v)
|
||||
{
|
||||
int p = pos[idx];
|
||||
Item old = data[idx];
|
||||
data[idx] = v;
|
||||
idx = (idx + 1) % N;
|
||||
sz = std::min<int>(sz + 1, N);
|
||||
if (p > 0) //new item is in minHeap
|
||||
{
|
||||
if (minCt < (N - 1) / 2)
|
||||
{
|
||||
++minCt;
|
||||
}
|
||||
else if (v > old)
|
||||
{
|
||||
minSortDown(p);
|
||||
return;
|
||||
}
|
||||
if (minSortUp(p) && mmCmpExch(0, -1))
|
||||
maxSortDown(-1);
|
||||
}
|
||||
else if (p < 0) //new item is in maxheap
|
||||
{
|
||||
if (maxCt < N / 2)
|
||||
{
|
||||
++maxCt;
|
||||
}
|
||||
else if (v < old)
|
||||
{
|
||||
maxSortDown(p);
|
||||
return;
|
||||
}
|
||||
if (maxSortUp(p) && minCt && mmCmpExch(1, 0))
|
||||
minSortDown(1);
|
||||
}
|
||||
else //new item is at median
|
||||
{
|
||||
if (maxCt && maxSortUp(-1))
|
||||
maxSortDown(-1);
|
||||
if (minCt && minSortUp(1))
|
||||
minSortDown(1);
|
||||
}
|
||||
}
|
||||
|
||||
//returns median item (or average of 2 when item count is even)
|
||||
Item median() const
|
||||
{
|
||||
Item v = data[heap[0]];
|
||||
if (minCt < maxCt)
|
||||
{
|
||||
v = (v + data[heap[-1]]) / 2;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -32,9 +32,6 @@
|
||||
#include "enableable.h"
|
||||
#include "keyvalue_serialization_overloads.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
/************************************************************************/
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/contains_fwd.hpp>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace epee
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
template<typename T, typename Tpod = T>
|
||||
class Stats
|
||||
{
|
||||
public:
|
||||
Stats(const std::vector<T> &v): values(v), cached(0) {}
|
||||
~Stats() {}
|
||||
|
||||
size_t get_size() const;
|
||||
Tpod get_min() const;
|
||||
Tpod get_max() const;
|
||||
Tpod get_median() const;
|
||||
double get_mean() const;
|
||||
double get_confidence_interval_95() const;
|
||||
double get_confidence_interval_99() const;
|
||||
double get_standard_deviation() const;
|
||||
double get_standard_error() const;
|
||||
double get_variance() const;
|
||||
double get_kurtosis() const;
|
||||
double get_non_parametric_skew() const;
|
||||
double get_t_test(T t) const;
|
||||
double get_t_test(size_t npoints, double mean, double stddev) const;
|
||||
double get_t_test(const Stats<T> &other) const;
|
||||
double get_z_test(const Stats<T> &other) const;
|
||||
double get_test(const Stats<T> &other) const;
|
||||
std::vector<Tpod> get_quantiles(unsigned int quantiles) const;
|
||||
std::vector<size_t> get_bins(unsigned int bins) const;
|
||||
bool is_same_distribution_95(size_t npoints, double mean, double stddev) const;
|
||||
bool is_same_distribution_95(const Stats<T> &other) const;
|
||||
bool is_same_distribution_99(size_t npoints, double mean, double stddev) const;
|
||||
bool is_same_distribution_99(const Stats<T> &other) const;
|
||||
|
||||
double get_cdf95(size_t df) const;
|
||||
double get_cdf95(const Stats<T> &other) const;
|
||||
double get_cdf99(size_t df) const;
|
||||
double get_cdf99(const Stats<T> &other) const;
|
||||
|
||||
private:
|
||||
inline bool is_cached(int bit) const;
|
||||
inline void set_cached(int bit) const;
|
||||
|
||||
const std::vector<T> &values;
|
||||
|
||||
mutable uint64_t cached;
|
||||
mutable Tpod min;
|
||||
mutable Tpod max;
|
||||
mutable Tpod median;
|
||||
mutable double mean;
|
||||
mutable double standard_deviation;
|
||||
mutable double standard_error;
|
||||
mutable double variance;
|
||||
mutable double kurtosis;
|
||||
};
|
||||
|
||||
#include "stats.inl"
|
||||
@@ -1,359 +0,0 @@
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include "stats.h"
|
||||
|
||||
enum
|
||||
{
|
||||
bit_min = 0,
|
||||
bit_max,
|
||||
bit_median,
|
||||
bit_mean,
|
||||
bit_standard_deviation,
|
||||
bit_standard_error,
|
||||
bit_variance,
|
||||
bit_kurtosis,
|
||||
};
|
||||
|
||||
static inline double square(double x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline double interpolate(T v, T v0, double i0, T v1, double i1)
|
||||
{
|
||||
return i0 + (i1 - i0) * (v - v0) / (v1 - v0);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
inline bool Stats<T, Tpod>::is_cached(int bit) const
|
||||
{
|
||||
return cached & (1<<bit);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
inline void Stats<T, Tpod>::set_cached(int bit) const
|
||||
{
|
||||
cached |= 1<<bit;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
size_t Stats<T, Tpod>::get_size() const
|
||||
{
|
||||
return values.size();
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
Tpod Stats<T, Tpod>::get_min() const
|
||||
{
|
||||
if (!is_cached(bit_min))
|
||||
{
|
||||
min = std::numeric_limits<Tpod>::max();
|
||||
for (const T &v: values)
|
||||
min = std::min<Tpod>(min, v);
|
||||
set_cached(bit_min);
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
Tpod Stats<T, Tpod>::get_max() const
|
||||
{
|
||||
if (!is_cached(bit_max))
|
||||
{
|
||||
max = std::numeric_limits<Tpod>::min();
|
||||
for (const T &v: values)
|
||||
max = std::max<Tpod>(max, v);
|
||||
set_cached(bit_max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
Tpod Stats<T, Tpod>::get_median() const
|
||||
{
|
||||
if (!is_cached(bit_median))
|
||||
{
|
||||
std::vector<Tpod> sorted;
|
||||
sorted.reserve(values.size());
|
||||
for (const T &v: values)
|
||||
sorted.push_back(v);
|
||||
std::sort(sorted.begin(), sorted.end());
|
||||
if (sorted.size() & 1)
|
||||
{
|
||||
median = sorted[sorted.size() / 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
median = (sorted[(sorted.size() - 1) / 2] + sorted[sorted.size() / 2]) / 2;
|
||||
}
|
||||
set_cached(bit_median);
|
||||
}
|
||||
return median;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_mean() const
|
||||
{
|
||||
if (values.empty())
|
||||
return 0.0;
|
||||
if (!is_cached(bit_mean))
|
||||
{
|
||||
mean = 0.0;
|
||||
for (const T &v: values)
|
||||
mean += v;
|
||||
mean /= values.size();
|
||||
set_cached(bit_mean);
|
||||
}
|
||||
return mean;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_cdf95(size_t df) const
|
||||
{
|
||||
static const double p[101] = {
|
||||
-1, 12.706, 4.3027, 3.1824, 2.7765, 2.5706, 2.4469, 2.3646, 2.3060, 2.2622, 2.2281, 2.2010, 2.1788, 2.1604, 2.1448, 2.1315,
|
||||
2.1199, 2.1098, 2.1009, 2.0930, 2.0860, 2.0796, 2.0739, 2.0687, 2.0639, 2.0595, 2.0555, 2.0518, 2.0484, 2.0452, 2.0423, 2.0395,
|
||||
2.0369, 2.0345, 2.0322, 2.0301, 2.0281, 2.0262, 2.0244, 2.0227, 2.0211, 2.0195, 2.0181, 2.0167, 2.0154, 2.0141, 2.0129, 2.0117,
|
||||
2.0106, 2.0096, 2.0086, 2.0076, 2.0066, 2.0057, 2.0049, 2.0040, 2.0032, 2.0025, 2.0017, 2.0010, 2.0003, 1.9996, 1.9990, 1.9983,
|
||||
1.9977, 1.9971, 1.9966, 1.9960, 1.9955, 1.9949, 1.9944, 1.9939, 1.9935, 1.9930, 1.9925, 1.9921, 1.9917, 1.9913, 1.9908, 1.9905,
|
||||
1.9901, 1.9897, 1.9893, 1.9890, 1.9886, 1.9883, 1.9879, 1.9876, 1.9873, 1.9870, 1.9867, 1.9864, 1.9861, 1.9858, 1.9855, 1.9852,
|
||||
1.9850, 1.9847, 1.9845, 1.9842, 1.9840,
|
||||
};
|
||||
if (df <= 100)
|
||||
return p[df];
|
||||
if (df <= 120)
|
||||
return interpolate<size_t>(df, 100, 1.9840, 120, 1.98);
|
||||
return 1.96;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_cdf95(const Stats<T> &other) const
|
||||
{
|
||||
return get_cdf95(get_size() + other.get_size() - 2);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_cdf99(size_t df) const
|
||||
{
|
||||
static const double p[101] = {
|
||||
-1, 9.9250, 5.8408, 4.6041, 4.0321, 3.7074, 3.4995, 3.3554, 3.2498, 3.1693, 3.1058, 3.0545, 3.0123, 2.9768, 2.9467, 2.9208, 2.8982,
|
||||
2.8784, 2.8609, 2.8453, 2.8314, 2.8188, 2.8073, 2.7970, 2.7874, 2.7787, 2.7707, 2.7633, 2.7564, 2.7500, 2.7440, 2.7385, 2.7333,
|
||||
2.7284, 2.7238, 2.7195, 2.7154, 2.7116, 2.7079, 2.7045, 2.7012, 2.6981, 2.6951, 2.6923, 2.6896, 2.6870, 2.6846, 2.6822, 2.6800,
|
||||
2.6778, 2.6757, 2.6737, 2.6718, 2.6700, 2.6682, 2.6665, 2.6649, 2.6633, 2.6618, 2.6603, 2.6589, 2.6575, 2.6561, 2.6549, 2.6536,
|
||||
2.6524, 2.6512, 2.6501, 2.6490, 2.6479, 2.6469, 2.6458, 2.6449, 2.6439, 2.6430, 2.6421, 2.6412, 2.6403, 2.6395, 2.6387, 2.6379,
|
||||
2.6371, 2.6364, 2.6356, 2.6349, 2.6342, 2.6335, 2.6329, 2.6322, 2.6316, 2.6309, 2.6303, 2.6297, 2.6291, 2.6286, 2.6280, 2.6275,
|
||||
2.6269, 2.6264, 2.6259,
|
||||
};
|
||||
if (df <= 100)
|
||||
return p[df];
|
||||
if (df <= 120)
|
||||
return interpolate<size_t>(df, 100, 2.6529, 120, 2.617);
|
||||
return 2.576;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_cdf99(const Stats<T> &other) const
|
||||
{
|
||||
return get_cdf99(get_size() + other.get_size() - 2);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_confidence_interval_95() const
|
||||
{
|
||||
const size_t df = get_size() - 1;
|
||||
return get_standard_error() * get_cdf95(df);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_confidence_interval_99() const
|
||||
{
|
||||
const size_t df = get_size() - 1;
|
||||
return get_standard_error() * get_cdf99(df);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
bool Stats<T, Tpod>::is_same_distribution_95(size_t npoints, double mean, double stddev) const
|
||||
{
|
||||
return fabs(get_t_test(npoints, mean, stddev)) < get_cdf95(get_size() + npoints - 2);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
bool Stats<T, Tpod>::is_same_distribution_95(const Stats<T> &other) const
|
||||
{
|
||||
return fabs(get_t_test(other)) < get_cdf95(other);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
bool Stats<T, Tpod>::is_same_distribution_99(size_t npoints, double mean, double stddev) const
|
||||
{
|
||||
return fabs(get_t_test(npoints, mean, stddev)) < get_cdf99(get_size() + npoints - 2);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
bool Stats<T, Tpod>::is_same_distribution_99(const Stats<T> &other) const
|
||||
{
|
||||
return fabs(get_t_test(other)) < get_cdf99(other);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_standard_deviation() const
|
||||
{
|
||||
if (values.size() <= 1)
|
||||
return 0.0;
|
||||
if (!is_cached(bit_standard_deviation))
|
||||
{
|
||||
Tpod m = get_mean(), t = 0;
|
||||
for (const T &v: values)
|
||||
t += ((T)v - m) * ((T)v - m);
|
||||
standard_deviation = sqrt(t / ((double)values.size() - 1));
|
||||
set_cached(bit_standard_deviation);
|
||||
}
|
||||
return standard_deviation;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_standard_error() const
|
||||
{
|
||||
if (!is_cached(bit_standard_error))
|
||||
{
|
||||
standard_error = get_standard_deviation() / sqrt(get_size());
|
||||
set_cached(bit_standard_error);
|
||||
}
|
||||
return standard_error;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_variance() const
|
||||
{
|
||||
if (!is_cached(bit_variance))
|
||||
{
|
||||
double stddev = get_standard_deviation();
|
||||
variance = stddev * stddev;
|
||||
set_cached(bit_variance);
|
||||
}
|
||||
return variance;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_kurtosis() const
|
||||
{
|
||||
if (values.empty())
|
||||
return 0.0;
|
||||
if (!is_cached(bit_kurtosis))
|
||||
{
|
||||
double m = get_mean();
|
||||
double n = 0, d = 0;
|
||||
for (const T &v: values)
|
||||
{
|
||||
T p2 = (v - m) * (v - m);
|
||||
T p4 = p2 * p2;
|
||||
n += p4;
|
||||
d += p2;
|
||||
}
|
||||
n /= values.size();
|
||||
d /= values.size();
|
||||
d *= d;
|
||||
kurtosis = n / d;
|
||||
set_cached(bit_kurtosis);
|
||||
}
|
||||
return kurtosis;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_non_parametric_skew() const
|
||||
{
|
||||
return (get_mean() - get_median()) / get_standard_deviation();
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_t_test(T t) const
|
||||
{
|
||||
const double n = get_mean() - t;
|
||||
const double d = get_standard_deviation() / sqrt(get_size());
|
||||
return n / d;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_t_test(size_t npoints, double mean, double stddev) const
|
||||
{
|
||||
const double n = get_mean() - mean;
|
||||
const double d = sqrt(get_variance() / get_size() + square(stddev) / npoints);
|
||||
return n / d;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_t_test(const Stats<T> &other) const
|
||||
{
|
||||
const double n = get_mean() - other.get_mean();
|
||||
const double d = sqrt(get_variance() / get_size() + other.get_variance() / other.get_size());
|
||||
return n / d;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_z_test(const Stats<T> &other) const
|
||||
{
|
||||
const double m0 = get_mean();
|
||||
const double m1 = other.get_mean();
|
||||
const double sd0 = get_standard_deviation();
|
||||
const double sd1 = other.get_standard_deviation();
|
||||
const size_t s0 = get_size();
|
||||
const size_t s1 = other.get_size();
|
||||
|
||||
const double n = m0 - m1;
|
||||
const double d = sqrt(square(sd0 / sqrt(s0)) + square(sd1 / sqrt(s1)));
|
||||
|
||||
return n / d;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
double Stats<T, Tpod>::get_test(const Stats<T> &other) const
|
||||
{
|
||||
if (get_size() >= 30 && other.get_size() >= 30)
|
||||
return get_z_test(other);
|
||||
else
|
||||
return get_t_test(other);
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
std::vector<Tpod> Stats<T, Tpod>::get_quantiles(unsigned int quantiles) const
|
||||
{
|
||||
std::vector<Tpod> sorted;
|
||||
sorted.reserve(values.size());
|
||||
for (const T &v: values)
|
||||
sorted.push_back(v);
|
||||
std::sort(sorted.begin(), sorted.end());
|
||||
std::vector<Tpod> q(quantiles + 1, 0);
|
||||
for (unsigned int i = 1; i <= quantiles; ++i)
|
||||
{
|
||||
unsigned idx = (unsigned)ceil(values.size() * i / (double)quantiles);
|
||||
q[i] = sorted[idx - 1];
|
||||
}
|
||||
if (!is_cached(bit_min))
|
||||
{
|
||||
min = sorted.front();
|
||||
set_cached(bit_min);
|
||||
}
|
||||
q[0] = min;
|
||||
if (!is_cached(bit_max))
|
||||
{
|
||||
max = sorted.back();
|
||||
set_cached(bit_max);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
template<typename T, typename Tpod>
|
||||
std::vector<size_t> Stats<T, Tpod>::get_bins(unsigned int bins) const
|
||||
{
|
||||
std::vector<size_t> b(bins, 0);
|
||||
const double scale = 1.0 / (get_max() - get_min());
|
||||
const T base = get_min();
|
||||
for (const T &v: values)
|
||||
{
|
||||
unsigned int idx = (v - base) * scale;
|
||||
++b[idx];
|
||||
}
|
||||
return b;
|
||||
}
|
||||
@@ -42,14 +42,13 @@ namespace misc_utils
|
||||
// 4: alpha
|
||||
// 8: whitespace
|
||||
// 16: allowed in float but doesn't necessarily mean it's a float
|
||||
// 32: \ and " (end of verbatim string)
|
||||
static const constexpr uint8_t lut[256]={
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 0, 0, // 16
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32
|
||||
8, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 18, 0, // 48
|
||||
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 18, 0, // 48
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, // 64
|
||||
0, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 80
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 32, 0, 0, 0, // 96
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 96
|
||||
0, 4, 4, 4, 4, 22, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 112
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 128
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -131,7 +130,7 @@ namespace misc_utils
|
||||
std::string::const_iterator it = star_end_string;
|
||||
++it;
|
||||
std::string::const_iterator fi = it;
|
||||
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
|
||||
while (fi != buf_end && *fi != '\\' && *fi != '\"')
|
||||
++fi;
|
||||
val.assign(it, fi);
|
||||
val.reserve(std::distance(star_end_string, buf_end));
|
||||
|
||||
@@ -82,7 +82,6 @@ namespace epee
|
||||
struct array_entry_t
|
||||
{
|
||||
array_entry_t():m_it(m_array.end()){}
|
||||
array_entry_t(const array_entry_t& other):m_array(other.m_array), m_it(m_array.end()){}
|
||||
|
||||
const t_entry_type* get_first_val() const
|
||||
{
|
||||
|
||||
@@ -144,7 +144,7 @@ POP_WARNINGS
|
||||
{
|
||||
MTRACE("Converting std::string to uint64_t. Source: " << from);
|
||||
// String only contains digits
|
||||
if(std::all_of(from.begin(), from.end(), epee::misc_utils::parse::isdigit))
|
||||
if(std::all_of(from.begin(), from.end(), ::isdigit))
|
||||
to = boost::lexical_cast<uint64_t>(from);
|
||||
// MyMonero ISO 8061 timestamp (2017-05-06T16:27:06Z)
|
||||
else if (boost::regex_match (from, boost::regex("\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\dZ")))
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#include <type_traits>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "storages/parserse_base_utils.h"
|
||||
#include "hex.h"
|
||||
#include "memwipe.h"
|
||||
#include "mlocker.h"
|
||||
@@ -128,7 +126,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
|
||||
{
|
||||
for (char c : str_id)
|
||||
{
|
||||
if (!epee::misc_utils::parse::isdigit(c))
|
||||
if (!std::isdigit(c))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -208,15 +206,6 @@ POP_WARNINGS
|
||||
return boost::lexical_cast<std::string>(val);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
inline std::string to_string_hex(uint32_t val)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex << val;
|
||||
std::string s;
|
||||
ss >> s;
|
||||
return s;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline bool compare_no_case(const std::string& str1, const std::string& str2)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp memwipe.c
|
||||
connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp)
|
||||
|
||||
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp memwipe.c
|
||||
connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp)
|
||||
if (USE_READLINE AND GNU_READLINE_FOUND)
|
||||
add_library(epee_readline STATIC readline_buffer.cpp)
|
||||
endif()
|
||||
|
||||
@@ -47,14 +47,8 @@
|
||||
// TODO:
|
||||
#include "net/network_throttle-detail.hpp"
|
||||
|
||||
#if BOOST_VERSION >= 107000
|
||||
#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
|
||||
#else
|
||||
#define GET_IO_SERVICE(s) ((s).get_io_service())
|
||||
#endif
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.conn"
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
|
||||
|
||||
// ################################################################################################
|
||||
// local (TU local) headers
|
||||
@@ -65,15 +59,6 @@ namespace epee
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
boost::asio::ssl::context& get_context(connection_basic_shared_state* state)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(state != nullptr, "state shared_ptr cannot be null");
|
||||
return state->ssl_context;
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(t_connection_type type)
|
||||
{
|
||||
if (type == e_connection_type_NET)
|
||||
@@ -118,7 +103,7 @@ namespace net_utils
|
||||
// connection_basic_pimpl
|
||||
// ================================================================================================
|
||||
|
||||
connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_throttle(name), m_peer_number(0) { }
|
||||
connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_throttle(name) { }
|
||||
|
||||
// ================================================================================================
|
||||
// connection_basic
|
||||
@@ -128,58 +113,29 @@ connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_thro
|
||||
int connection_basic_pimpl::m_default_tos;
|
||||
|
||||
// methods:
|
||||
connection_basic::connection_basic(boost::asio::ip::tcp::socket&& sock, boost::shared_ptr<connection_basic_shared_state> state, ssl_support_t ssl_support)
|
||||
:
|
||||
m_state(std::move(state)),
|
||||
mI( new connection_basic_pimpl("peer") ),
|
||||
strand_(GET_IO_SERVICE(sock)),
|
||||
socket_(GET_IO_SERVICE(sock), get_context(m_state.get())),
|
||||
m_want_close_connection(false),
|
||||
m_was_shutdown(false),
|
||||
m_ssl_support(ssl_support)
|
||||
{
|
||||
// add nullptr checks if removed
|
||||
assert(m_state != nullptr); // release runtime check in get_context
|
||||
|
||||
socket_.next_layer() = std::move(sock);
|
||||
|
||||
++(m_state->sock_count); // increase the global counter
|
||||
mI->m_peer_number = m_state->sock_number.fetch_add(1); // use, and increase the generated number
|
||||
|
||||
std::string remote_addr_str = "?";
|
||||
try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
|
||||
|
||||
_note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_state->sock_count);
|
||||
}
|
||||
|
||||
connection_basic::connection_basic(boost::asio::io_service &io_service, boost::shared_ptr<connection_basic_shared_state> state, ssl_support_t ssl_support)
|
||||
:
|
||||
m_state(std::move(state)),
|
||||
connection_basic::connection_basic(boost::asio::io_service& io_service, std::atomic<long> &ref_sock_count, std::atomic<long> &sock_number)
|
||||
:
|
||||
mI( new connection_basic_pimpl("peer") ),
|
||||
strand_(io_service),
|
||||
socket_(io_service, get_context(m_state.get())),
|
||||
m_want_close_connection(false),
|
||||
socket_(io_service),
|
||||
m_want_close_connection(false),
|
||||
m_was_shutdown(false),
|
||||
m_ssl_support(ssl_support)
|
||||
{
|
||||
// add nullptr checks if removed
|
||||
assert(m_state != nullptr); // release runtime check in get_context
|
||||
|
||||
++(m_state->sock_count); // increase the global counter
|
||||
mI->m_peer_number = m_state->sock_number.fetch_add(1); // use, and increase the generated number
|
||||
m_ref_sock_count(ref_sock_count)
|
||||
{
|
||||
++ref_sock_count; // increase the global counter
|
||||
mI->m_peer_number = sock_number.fetch_add(1); // use, and increase the generated number
|
||||
|
||||
std::string remote_addr_str = "?";
|
||||
try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
|
||||
try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ;
|
||||
|
||||
_note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_state->sock_count);
|
||||
_note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_ref_sock_count);
|
||||
}
|
||||
|
||||
connection_basic::~connection_basic() noexcept(false) {
|
||||
--(m_state->sock_count);
|
||||
|
||||
std::string remote_addr_str = "?";
|
||||
try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
|
||||
_note("Destructing connection #"<<mI->m_peer_number << " to " << remote_addr_str);
|
||||
m_ref_sock_count--;
|
||||
try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ;
|
||||
_note("Destructing connection p2p#"<<mI->m_peer_number << " to " << remote_addr_str);
|
||||
}
|
||||
|
||||
void connection_basic::set_rate_up_limit(uint64_t limit) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -83,67 +83,4 @@ namespace epee
|
||||
{
|
||||
return write_hex(out, src);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> from_hex::vector(boost::string_ref src)
|
||||
{
|
||||
// should we include a specific character
|
||||
auto include = [](char input) {
|
||||
// we ignore spaces and colons
|
||||
return !std::isspace(input) && input != ':';
|
||||
};
|
||||
|
||||
// the number of relevant characters to decode
|
||||
auto count = std::count_if(src.begin(), src.end(), include);
|
||||
|
||||
// this must be a multiple of two, otherwise we have a truncated input
|
||||
if (count % 2) {
|
||||
throw std::length_error{ "Invalid hexadecimal input length" };
|
||||
}
|
||||
|
||||
std::vector<uint8_t> result;
|
||||
result.reserve(count / 2);
|
||||
|
||||
// the data to work with (std::string is always null-terminated)
|
||||
auto data = src.data();
|
||||
|
||||
// convert a single hex character to an unsigned integer
|
||||
auto char_to_int = [](const char *input) {
|
||||
switch (std::tolower(*input)) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
case 'a': return 10;
|
||||
case 'b': return 11;
|
||||
case 'c': return 12;
|
||||
case 'd': return 13;
|
||||
case 'e': return 14;
|
||||
case 'f': return 15;
|
||||
default: throw std::range_error{ "Invalid hexadecimal input" };
|
||||
}
|
||||
};
|
||||
|
||||
// keep going until we reach the end
|
||||
while (data[0] != '\0') {
|
||||
// skip unwanted characters
|
||||
if (!include(data[0])) {
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
|
||||
// convert two matching characters to int
|
||||
auto high = char_to_int(data++);
|
||||
auto low = char_to_int(data++);
|
||||
|
||||
result.push_back(high << 4 | low);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
||||
@@ -100,7 +100,7 @@ static const char *get_default_categories(int level)
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
categories = "*:WARNING,net:FATAL,net.http:FATAL,net.ssl:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,serialization:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO";
|
||||
categories = "*:WARNING,net:FATAL,net.http:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO";
|
||||
break;
|
||||
case 1:
|
||||
categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG";
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#include "net/net_helper.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
boost::unique_future<boost::asio::ip::tcp::socket>
|
||||
direct_connect::operator()(const std::string& addr, const std::string& port, boost::asio::steady_timer& timeout) const
|
||||
{
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
boost::asio::ip::tcp::resolver resolver(GET_IO_SERVICE(timeout));
|
||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name);
|
||||
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if(iterator == end) // Documentation states that successful call is guaranteed to be non-empty
|
||||
throw boost::system::system_error{boost::asio::error::fault, "Failed to resolve " + addr};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct new_connection
|
||||
{
|
||||
boost::promise<boost::asio::ip::tcp::socket> result_;
|
||||
boost::asio::ip::tcp::socket socket_;
|
||||
|
||||
explicit new_connection(boost::asio::io_service& io_service)
|
||||
: result_(), socket_(io_service)
|
||||
{}
|
||||
};
|
||||
|
||||
const auto shared = std::make_shared<new_connection>(GET_IO_SERVICE(timeout));
|
||||
timeout.async_wait([shared] (boost::system::error_code error)
|
||||
{
|
||||
if (error != boost::system::errc::operation_canceled && shared && shared->socket_.is_open())
|
||||
{
|
||||
shared->socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
shared->socket_.close();
|
||||
}
|
||||
});
|
||||
shared->socket_.async_connect(*iterator, [shared] (boost::system::error_code error)
|
||||
{
|
||||
if (shared)
|
||||
{
|
||||
if (error)
|
||||
shared->result_.set_exception(boost::system::system_error{error});
|
||||
else
|
||||
shared->result_.set_value(std::move(shared->socket_));
|
||||
}
|
||||
});
|
||||
return shared->result_.get_future();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,531 +0,0 @@
|
||||
// Copyright (c) 2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <string.h>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "misc_log_ex.h"
|
||||
#include "net/net_ssl.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.ssl"
|
||||
|
||||
// openssl genrsa -out /tmp/KEY 4096
|
||||
// openssl req -new -key /tmp/KEY -out /tmp/REQ
|
||||
// openssl x509 -req -days 999999 -sha256 -in /tmp/REQ -signkey /tmp/KEY -out /tmp/CERT
|
||||
|
||||
namespace
|
||||
{
|
||||
struct openssl_bio_free
|
||||
{
|
||||
void operator()(BIO* ptr) const noexcept
|
||||
{
|
||||
BIO_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_bio = std::unique_ptr<BIO, openssl_bio_free>;
|
||||
|
||||
struct openssl_pkey_free
|
||||
{
|
||||
void operator()(EVP_PKEY* ptr) const noexcept
|
||||
{
|
||||
EVP_PKEY_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_pkey = std::unique_ptr<EVP_PKEY, openssl_pkey_free>;
|
||||
|
||||
struct openssl_rsa_free
|
||||
{
|
||||
void operator()(RSA* ptr) const noexcept
|
||||
{
|
||||
RSA_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_rsa = std::unique_ptr<RSA, openssl_rsa_free>;
|
||||
|
||||
struct openssl_bignum_free
|
||||
{
|
||||
void operator()(BIGNUM* ptr) const noexcept
|
||||
{
|
||||
BN_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_bignum = std::unique_ptr<BIGNUM, openssl_bignum_free>;
|
||||
|
||||
struct openssl_ec_key_free
|
||||
{
|
||||
void operator()(EC_KEY* ptr) const noexcept
|
||||
{
|
||||
EC_KEY_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_ec_key = std::unique_ptr<EC_KEY, openssl_ec_key_free>;
|
||||
|
||||
struct openssl_group_free
|
||||
{
|
||||
void operator()(EC_GROUP* ptr) const noexcept
|
||||
{
|
||||
EC_GROUP_free(ptr);
|
||||
}
|
||||
};
|
||||
using openssl_group = std::unique_ptr<EC_GROUP, openssl_group_free>;
|
||||
|
||||
boost::system::error_code load_ca_file(boost::asio::ssl::context& ctx, const std::string& path)
|
||||
{
|
||||
SSL_CTX* const ssl_ctx = ctx.native_handle(); // could be moved from context
|
||||
if (ssl_ctx == nullptr)
|
||||
return {boost::asio::error::invalid_argument};
|
||||
|
||||
if (!SSL_CTX_load_verify_locations(ssl_ctx, path.c_str(), nullptr))
|
||||
{
|
||||
return boost::system::error_code{
|
||||
int(::ERR_get_error()), boost::asio::error::get_ssl_category()
|
||||
};
|
||||
}
|
||||
return boost::system::error_code{};
|
||||
}
|
||||
}
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
|
||||
// https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl
|
||||
bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
|
||||
{
|
||||
MGINFO("Generating SSL certificate");
|
||||
pkey = EVP_PKEY_new();
|
||||
if (!pkey)
|
||||
{
|
||||
MERROR("Failed to create new private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
openssl_pkey pkey_deleter{pkey};
|
||||
openssl_rsa rsa{RSA_new()};
|
||||
if (!rsa)
|
||||
{
|
||||
MERROR("Error allocating RSA private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
openssl_bignum exponent{BN_new()};
|
||||
if (!exponent)
|
||||
{
|
||||
MERROR("Error allocating exponent");
|
||||
return false;
|
||||
}
|
||||
|
||||
BN_set_word(exponent.get(), RSA_F4);
|
||||
|
||||
if (RSA_generate_key_ex(rsa.get(), 4096, exponent.get(), nullptr) != 1)
|
||||
{
|
||||
MERROR("Error generating RSA private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_assign_RSA(pkey, rsa.get()) <= 0)
|
||||
{
|
||||
MERROR("Error assigning RSA private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
// the RSA key is now managed by the EVP_PKEY structure
|
||||
(void)rsa.release();
|
||||
|
||||
cert = X509_new();
|
||||
if (!cert)
|
||||
{
|
||||
MERROR("Failed to create new X509 certificate");
|
||||
return false;
|
||||
}
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
|
||||
X509_gmtime_adj(X509_get_notBefore(cert), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(cert), 3600 * 24 * 182); // half a year
|
||||
if (!X509_set_pubkey(cert, pkey))
|
||||
{
|
||||
MERROR("Error setting pubkey on certificate");
|
||||
X509_free(cert);
|
||||
return false;
|
||||
}
|
||||
X509_NAME *name = X509_get_subject_name(cert);
|
||||
X509_set_issuer_name(cert, name);
|
||||
|
||||
if (X509_sign(cert, pkey, EVP_sha256()) == 0)
|
||||
{
|
||||
MERROR("Error signing certificate");
|
||||
X509_free(cert);
|
||||
return false;
|
||||
}
|
||||
(void)pkey_deleter.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert, int type)
|
||||
{
|
||||
MGINFO("Generating SSL certificate");
|
||||
pkey = EVP_PKEY_new();
|
||||
if (!pkey)
|
||||
{
|
||||
MERROR("Failed to create new private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
openssl_pkey pkey_deleter{pkey};
|
||||
openssl_ec_key ec_key{EC_KEY_new()};
|
||||
if (!ec_key)
|
||||
{
|
||||
MERROR("Error allocating EC private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
EC_GROUP *group = EC_GROUP_new_by_curve_name(type);
|
||||
if (!group)
|
||||
{
|
||||
MERROR("Error getting EC group " << type);
|
||||
return false;
|
||||
}
|
||||
openssl_group group_deleter{group};
|
||||
|
||||
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
|
||||
EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
|
||||
|
||||
if (!EC_GROUP_check(group, NULL))
|
||||
{
|
||||
MERROR("Group failed check: " << ERR_reason_error_string(ERR_get_error()));
|
||||
return false;
|
||||
}
|
||||
if (EC_KEY_set_group(ec_key.get(), group) != 1)
|
||||
{
|
||||
MERROR("Error setting EC group");
|
||||
return false;
|
||||
}
|
||||
if (EC_KEY_generate_key(ec_key.get()) != 1)
|
||||
{
|
||||
MERROR("Error generating EC private key");
|
||||
return false;
|
||||
}
|
||||
if (EVP_PKEY_assign_EC_KEY(pkey, ec_key.get()) <= 0)
|
||||
{
|
||||
MERROR("Error assigning EC private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
// the key is now managed by the EVP_PKEY structure
|
||||
(void)ec_key.release();
|
||||
|
||||
cert = X509_new();
|
||||
if (!cert)
|
||||
{
|
||||
MERROR("Failed to create new X509 certificate");
|
||||
return false;
|
||||
}
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
|
||||
X509_gmtime_adj(X509_get_notBefore(cert), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(cert), 3600 * 24 * 182); // half a year
|
||||
if (!X509_set_pubkey(cert, pkey))
|
||||
{
|
||||
MERROR("Error setting pubkey on certificate");
|
||||
X509_free(cert);
|
||||
return false;
|
||||
}
|
||||
X509_NAME *name = X509_get_subject_name(cert);
|
||||
X509_set_issuer_name(cert, name);
|
||||
|
||||
if (X509_sign(cert, pkey, EVP_sha256()) == 0)
|
||||
{
|
||||
MERROR("Error signing certificate");
|
||||
X509_free(cert);
|
||||
return false;
|
||||
}
|
||||
(void)pkey_deleter.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
ssl_options_t::ssl_options_t(std::vector<std::vector<std::uint8_t>> fingerprints, std::string ca_path)
|
||||
: fingerprints_(std::move(fingerprints)),
|
||||
ca_path(std::move(ca_path)),
|
||||
auth(),
|
||||
support(ssl_support_t::e_ssl_support_enabled),
|
||||
verification(ssl_verification_t::user_certificates)
|
||||
{
|
||||
std::sort(fingerprints_.begin(), fingerprints_.end());
|
||||
}
|
||||
|
||||
boost::asio::ssl::context ssl_options_t::create_context() const
|
||||
{
|
||||
boost::asio::ssl::context ssl_context{boost::asio::ssl::context::tlsv12};
|
||||
if (!bool(*this))
|
||||
return ssl_context;
|
||||
|
||||
// only allow tls v1.2 and up
|
||||
ssl_context.set_options(boost::asio::ssl::context::default_workarounds);
|
||||
ssl_context.set_options(boost::asio::ssl::context::no_sslv2);
|
||||
ssl_context.set_options(boost::asio::ssl::context::no_sslv3);
|
||||
ssl_context.set_options(boost::asio::ssl::context::no_tlsv1);
|
||||
ssl_context.set_options(boost::asio::ssl::context::no_tlsv1_1);
|
||||
|
||||
// only allow a select handful of tls v1.3 and v1.2 ciphers to be used
|
||||
SSL_CTX_set_cipher_list(ssl_context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256");
|
||||
|
||||
// set options on the SSL context for added security
|
||||
SSL_CTX *ctx = ssl_context.native_handle();
|
||||
CHECK_AND_ASSERT_THROW_MES(ctx, "Failed to get SSL context");
|
||||
SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT); // SSL_CTX_SET_OPTIONS(3)
|
||||
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); // https://stackoverflow.com/questions/22378442
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); // https://stackoverflow.com/questions/22378442
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
|
||||
#endif
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||
#endif
|
||||
SSL_CTX_set_ecdh_auto(ctx, 1);
|
||||
|
||||
switch (verification)
|
||||
{
|
||||
case ssl_verification_t::system_ca:
|
||||
ssl_context.set_default_verify_paths();
|
||||
break;
|
||||
case ssl_verification_t::user_certificates:
|
||||
ssl_context.set_verify_depth(0);
|
||||
/* fallthrough */
|
||||
case ssl_verification_t::user_ca:
|
||||
if (!ca_path.empty())
|
||||
{
|
||||
const boost::system::error_code err = load_ca_file(ssl_context, ca_path);
|
||||
if (err)
|
||||
throw boost::system::system_error{err, "Failed to load user CA file at " + ca_path};
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(auth.private_key_path.empty() == auth.certificate_path.empty(), "private key and certificate must be either both given or both empty");
|
||||
if (auth.private_key_path.empty())
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
X509 *cert;
|
||||
bool ok = false;
|
||||
|
||||
#ifdef USE_EXTRA_EC_CERT
|
||||
CHECK_AND_ASSERT_THROW_MES(create_ec_ssl_certificate(pkey, cert, NID_secp256k1), "Failed to create certificate");
|
||||
CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
|
||||
if (!SSL_CTX_use_PrivateKey(ctx, pkey))
|
||||
MERROR("Failed to use generated EC private key for " << NID_secp256k1);
|
||||
else
|
||||
ok = true;
|
||||
X509_free(cert);
|
||||
EVP_PKEY_free(pkey);
|
||||
#endif
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(create_rsa_ssl_certificate(pkey, cert), "Failed to create certificate");
|
||||
CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
|
||||
if (!SSL_CTX_use_PrivateKey(ctx, pkey))
|
||||
MERROR("Failed to use generated RSA private key for RSA");
|
||||
else
|
||||
ok = true;
|
||||
X509_free(cert);
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(ok, "Failed to use any generated certificate");
|
||||
}
|
||||
else
|
||||
auth.use_ssl_certificate(ssl_context);
|
||||
|
||||
return ssl_context;
|
||||
}
|
||||
|
||||
void ssl_authentication_t::use_ssl_certificate(boost::asio::ssl::context &ssl_context) const
|
||||
{
|
||||
ssl_context.use_private_key_file(private_key_path, boost::asio::ssl::context::pem);
|
||||
ssl_context.use_certificate_chain_file(certificate_path);
|
||||
}
|
||||
|
||||
bool is_ssl(const unsigned char *data, size_t len)
|
||||
{
|
||||
if (len < get_ssl_magic_size())
|
||||
return false;
|
||||
|
||||
// https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification
|
||||
MDEBUG("SSL detection buffer, " << len << " bytes: "
|
||||
<< (unsigned)(unsigned char)data[0] << " " << (unsigned)(unsigned char)data[1] << " "
|
||||
<< (unsigned)(unsigned char)data[2] << " " << (unsigned)(unsigned char)data[3] << " "
|
||||
<< (unsigned)(unsigned char)data[4] << " " << (unsigned)(unsigned char)data[5] << " "
|
||||
<< (unsigned)(unsigned char)data[6] << " " << (unsigned)(unsigned char)data[7] << " "
|
||||
<< (unsigned)(unsigned char)data[8]);
|
||||
if (data[0] == 0x16) // record
|
||||
if (data[1] == 3) // major version
|
||||
if (data[5] == 1) // ClientHello
|
||||
if (data[6] == 0 && data[3]*256 + data[4] == data[7]*256 + data[8] + 4) // length check
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ssl_options_t::has_strong_verification(boost::string_ref host) const noexcept
|
||||
{
|
||||
// onion and i2p addresses contain information about the server cert
|
||||
// which both authenticates and encrypts
|
||||
if (host.ends_with(".onion") || host.ends_with(".i2p"))
|
||||
return true;
|
||||
switch (verification)
|
||||
{
|
||||
default:
|
||||
case ssl_verification_t::none:
|
||||
case ssl_verification_t::system_ca:
|
||||
return false;
|
||||
case ssl_verification_t::user_certificates:
|
||||
case ssl_verification_t::user_ca:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
|
||||
{
|
||||
// can we check the certificate against a list of fingerprints?
|
||||
if (!fingerprints_.empty()) {
|
||||
X509_STORE_CTX *sctx = ctx.native_handle();
|
||||
if (!sctx)
|
||||
{
|
||||
MERROR("Error getting verify_context handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
X509* cert = nullptr;
|
||||
const STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(sctx);
|
||||
if (!chain || sk_X509_num(chain) < 1 || !(cert = sk_X509_value(chain, 0)))
|
||||
{
|
||||
MERROR("No certificate found in verify_context");
|
||||
return false;
|
||||
}
|
||||
|
||||
// buffer for the certificate digest and the size of the result
|
||||
std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
|
||||
unsigned int size{ 0 };
|
||||
|
||||
// create the digest from the certificate
|
||||
if (!X509_digest(cert, EVP_sha256(), digest.data(), &size)) {
|
||||
MERROR("Failed to create certificate fingerprint");
|
||||
return false;
|
||||
}
|
||||
|
||||
// strip unnecessary bytes from the digest
|
||||
digest.resize(size);
|
||||
|
||||
return std::binary_search(fingerprints_.begin(), fingerprints_.end(), digest);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ssl_options_t::handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const std::string& host) const
|
||||
{
|
||||
socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
|
||||
/* Using system-wide CA store for client verification is funky - there is
|
||||
no expected hostname for server to verify against. If server doesn't have
|
||||
specific whitelisted certificates for client, don't require client to
|
||||
send certificate at all. */
|
||||
const bool no_verification = verification == ssl_verification_t::none ||
|
||||
(type == boost::asio::ssl::stream_base::server && fingerprints_.empty() && ca_path.empty());
|
||||
|
||||
/* According to OpenSSL documentation (and SSL specifications), server must
|
||||
always send certificate unless "anonymous" cipher mode is used which are
|
||||
disabled by default. Either way, the certificate is never inspected. */
|
||||
if (no_verification)
|
||||
socket.set_verify_mode(boost::asio::ssl::verify_none);
|
||||
else
|
||||
{
|
||||
socket.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
|
||||
// in case server is doing "virtual" domains, set hostname
|
||||
SSL* const ssl_ctx = socket.native_handle();
|
||||
if (type == boost::asio::ssl::stream_base::client && !host.empty() && ssl_ctx)
|
||||
SSL_set_tlsext_host_name(ssl_ctx, host.c_str());
|
||||
|
||||
socket.set_verify_callback([&](const bool preverified, boost::asio::ssl::verify_context &ctx)
|
||||
{
|
||||
// preverified means it passed system or user CA check. System CA is never loaded
|
||||
// when fingerprints are whitelisted.
|
||||
const bool verified = preverified &&
|
||||
(verification != ssl_verification_t::system_ca || host.empty() || boost::asio::ssl::rfc2818_verification(host)(preverified, ctx));
|
||||
|
||||
if (!verified && !has_fingerprint(ctx))
|
||||
{
|
||||
// autodetect will reconnect without SSL - warn and keep connection encrypted
|
||||
if (support != ssl_support_t::e_ssl_support_autodetect)
|
||||
{
|
||||
MERROR("SSL certificate is not in the allowed list, connection droppped");
|
||||
return false;
|
||||
}
|
||||
MWARNING("SSL peer has not been verified");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
socket.handshake(type, ec);
|
||||
if (ec)
|
||||
{
|
||||
MERROR("SSL handshake failed, connection dropped: " << ec.message());
|
||||
return false;
|
||||
}
|
||||
MDEBUG("SSL handshake success");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
|
||||
{
|
||||
if (s == "enabled")
|
||||
ssl = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
|
||||
else if (s == "disabled")
|
||||
ssl = epee::net_utils::ssl_support_t::e_ssl_support_disabled;
|
||||
else if (s == "autodetect")
|
||||
ssl = epee::net_utils::ssl_support_t::e_ssl_support_autodetect;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
namespace epee { namespace net_utils
|
||||
{
|
||||
const uint8_t ipv4_network_address::ID;
|
||||
|
||||
bool ipv4_network_address::equal(const ipv4_network_address& other) const noexcept
|
||||
{ return is_same_host(other) && port() == other.port(); }
|
||||
|
||||
@@ -56,6 +58,20 @@ namespace epee { namespace net_utils
|
||||
return self_->is_same_host(*other_self);
|
||||
}
|
||||
|
||||
bool create_network_address(network_address &address, const std::string &string, uint16_t default_port)
|
||||
{
|
||||
uint32_t ip;
|
||||
uint16_t port;
|
||||
if (epee::string_tools::parse_peer_from_string(ip, port, string))
|
||||
{
|
||||
if (default_port && !port)
|
||||
port = default_port;
|
||||
address = ipv4_network_address{ip, port};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string print_connection_context(const connection_context_base& ctx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@@ -70,31 +86,5 @@ namespace epee { namespace net_utils
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const char* zone_to_string(zone value) noexcept
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case zone::public_:
|
||||
return "public";
|
||||
case zone::i2p:
|
||||
return "i2p";
|
||||
case zone::tor:
|
||||
return "tor";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
zone zone_from_string(const boost::string_ref value) noexcept
|
||||
{
|
||||
if (value == "public")
|
||||
return zone::public_;
|
||||
if (value == "i2p")
|
||||
return zone::i2p;
|
||||
if (value == "tor")
|
||||
return zone::tor;
|
||||
return zone::invalid;
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
@@ -135,9 +135,6 @@ network_throttle::network_throttle(const std::string &nameshort, const std::stri
|
||||
m_slot_size = 1.0; // hard coded in few places
|
||||
m_target_speed = 16 * 1024; // other defaults are probably defined in the command-line parsing code when this class is used e.g. as main global throttle
|
||||
m_last_sample_time = 0;
|
||||
m_history.resize(m_window_size);
|
||||
m_total_packets = 0;
|
||||
m_total_bytes = 0;
|
||||
}
|
||||
|
||||
void network_throttle::set_name(const std::string &name)
|
||||
@@ -171,7 +168,8 @@ void network_throttle::tick()
|
||||
{
|
||||
_dbg3("Moving counter buffer by 1 second " << last_sample_time_slot << " < " << current_sample_time_slot << " (last time " << m_last_sample_time<<")");
|
||||
// rotate buffer
|
||||
m_history.push_front(packet_info());
|
||||
for (size_t i=m_history.size()-1; i>=1; --i) m_history[i] = m_history[i-1];
|
||||
m_history[0] = packet_info();
|
||||
if (! m_any_packet_yet)
|
||||
{
|
||||
m_last_sample_time = time_now;
|
||||
@@ -193,9 +191,7 @@ void network_throttle::_handle_trafic_exact(size_t packet_size, size_t orginal_s
|
||||
|
||||
calculate_times_struct cts ; calculate_times(packet_size, cts , false, -1);
|
||||
calculate_times_struct cts2; calculate_times(packet_size, cts2, false, 5);
|
||||
m_history.front().m_size += packet_size;
|
||||
m_total_packets++;
|
||||
m_total_bytes += packet_size;
|
||||
m_history[0].m_size += packet_size;
|
||||
|
||||
std::ostringstream oss; oss << "["; for (auto sample: m_history) oss << sample.m_size << " "; oss << "]" << std::ends;
|
||||
std::string history_str = oss.str();
|
||||
@@ -356,12 +352,6 @@ double network_throttle::get_current_speed() const {
|
||||
return bytes_transferred / ((m_history.size() - 1) * m_slot_size);
|
||||
}
|
||||
|
||||
void network_throttle::get_stats(uint64_t &total_packets, uint64_t &total_bytes) const {
|
||||
total_packets = m_total_packets;
|
||||
total_bytes = m_total_bytes;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2017-2019, The Monero Project
|
||||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace tests
|
||||
{
|
||||
const static int ID = 1000;
|
||||
|
||||
struct request_t
|
||||
struct request
|
||||
{
|
||||
|
||||
std::string example_string_data;
|
||||
@@ -75,9 +75,9 @@ namespace tests
|
||||
SERIALIZE_T(sub)
|
||||
END_NAMED_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
|
||||
struct response
|
||||
{
|
||||
bool m_success;
|
||||
uint64_t example_id_data;
|
||||
@@ -89,14 +89,13 @@ namespace tests
|
||||
SERIALIZE_STL_CONTAINER_T(subs)
|
||||
END_NAMED_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_EXAMPLE_2
|
||||
{
|
||||
const static int ID = 1001;
|
||||
|
||||
struct request_t
|
||||
struct request
|
||||
{
|
||||
std::string example_string_data2;
|
||||
uint64_t example_id_data;
|
||||
@@ -106,9 +105,8 @@ namespace tests
|
||||
SERIALIZE_STL_ANSI_STRING(example_string_data2)
|
||||
END_NAMED_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
struct response
|
||||
{
|
||||
bool m_success;
|
||||
uint64_t example_id_data;
|
||||
@@ -118,7 +116,6 @@ namespace tests
|
||||
SERIALIZE_POD(m_success)
|
||||
END_NAMED_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
typedef boost::uuids::uuid uuid;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Gitian building
|
||||
================
|
||||
|
||||
*Setup instructions for a Gitian build of Monero.*
|
||||
*Setup instructions for a Gitian build of Monero using a VM or physical system.*
|
||||
|
||||
Gitian is the deterministic build process that is used to build the Monero CLI
|
||||
executables. It provides a way to be reasonably sure that the
|
||||
@@ -13,10 +13,6 @@ Multiple developers build the source code by following a specific descriptor
|
||||
These results are compared and only if they match, the build is accepted and provided
|
||||
for download.
|
||||
|
||||
Gitian runs compilation steps in an isolated container. It is flexible and gives you full
|
||||
control over the build environment, while still ensuring reproducibility and consistent output
|
||||
formats.
|
||||
|
||||
More independent Gitian builders are needed, which is why this guide exists.
|
||||
It is preferred you follow these steps yourself instead of using someone else's
|
||||
VM image to avoid 'contaminating' the build.
|
||||
@@ -26,17 +22,11 @@ Preparing the Gitian builder host
|
||||
|
||||
The first step is to prepare the host environment that will be used to perform the Gitian builds.
|
||||
This guide explains how to set up the environment, and how to start the builds.
|
||||
Gitian offers to build with either `kvm`, `docker` or `lxc`. The default build
|
||||
path chosen is `lxc`, but its setup is more complicated. You need to be logged in as the `gitianuser`.
|
||||
If this user does not exist yet on your system, create it. Gitian can use
|
||||
either kvm, lxc or docker as a host environment. This documentation will show
|
||||
how to build with lxc and docker. While the docker setup is easy, the lxc setup
|
||||
is more involved.
|
||||
|
||||
LXC
|
||||
---
|
||||
|
||||
LXC builds should be run on Ubuntu 18.04 "Bionic Beaver".
|
||||
Gitian builds are for now executed on Ubuntu 18.04 "Bionic Beaver". A solution is being worked on to run
|
||||
it in docker in the future. Please run Ubuntu in either a VM, or on your physical machine.
|
||||
You need to be logged in as the `gitianuser` in order to build gitian builds. If this user does not exist yet on your system,
|
||||
create it.
|
||||
|
||||
Note that a version of `lxc-execute` higher or equal to 2.1.1 is required.
|
||||
You can check the version with `lxc-execute --version`.
|
||||
@@ -73,28 +63,15 @@ reboot
|
||||
|
||||
This setup is required to enable networking in the container.
|
||||
|
||||
Docker
|
||||
------
|
||||
|
||||
Building in docker does not require much setup. Install docker on your host, then type the following:
|
||||
|
||||
```bash
|
||||
sudo apt-get install git make curl
|
||||
sudo usermod -aG docker gitianuser
|
||||
```
|
||||
|
||||
|
||||
Manual and Building
|
||||
-------------------
|
||||
|
||||
The instructions below use the automated script [gitian-build.py](gitian-build.py) which only works in Ubuntu.
|
||||
It calls all available .yml descriptors, which in turn pass the build configurations for different platforms to gitian.
|
||||
Help for the build steps taken can be accessed with `./gitian-build.py --help`.
|
||||
The instructions below use the automated script [gitian-build.py](https://github.com/betcoin/bitcoin/blob/master/contrib/gitian-build.py) which only works in Ubuntu.
|
||||
It calls all available descriptors. Help for the build steps taken can be accessed with `./gitian-build.py --help`.
|
||||
|
||||
Initial Gitian Setup
|
||||
--------------------
|
||||
|
||||
The `gitian-build.py` script will checkout different release tags, so it's best to copy it to the top level directory:
|
||||
The `gitian-build.py` script will checkout different release tags, so it's best to copy it:
|
||||
|
||||
```bash
|
||||
cp monero/contrib/gitian/gitian-build.py .
|
||||
@@ -102,16 +79,11 @@ cp monero/contrib/gitian/gitian-build.py .
|
||||
|
||||
Setup the required environment, you only need to do this once:
|
||||
|
||||
```bash
|
||||
```
|
||||
./gitian-build.py --setup fluffypony v0.14.0
|
||||
```
|
||||
|
||||
Where `fluffypony` is your Github name and `v0.14.0` is the version tag you want to build.
|
||||
If you are using docker, run it with:
|
||||
|
||||
```bash
|
||||
./gitian-build.py --setup --docker fluffypony v0.14.0
|
||||
```
|
||||
Where `fluffypony` is your Github name and `v0.14.0` is the version tag you want to build.
|
||||
|
||||
While gitian and this build script does provide a way for you to sign the build directly, it is recommended to sign in a seperate step.
|
||||
This script is only there for convenience. Seperate steps for building can still be taken.
|
||||
@@ -119,18 +91,16 @@ In order to sign gitian builds on your host machine, which has your PGP key,
|
||||
fork the gitian.sigs repository and clone it on your host machine,
|
||||
or pass the signed assert file back to your build machine.
|
||||
|
||||
```bash
|
||||
```
|
||||
git clone git@github.com:monero-project/gitian.sigs.git
|
||||
git remote add fluffypony git@github.com:fluffypony/gitian.sigs.git
|
||||
```
|
||||
|
||||
Build Binaries
|
||||
-----------------------------
|
||||
To build the most recent tag (pass in `--docker` after setting up with docker):
|
||||
To build the most recent tag:
|
||||
|
||||
```bash
|
||||
./gitian-build.py --detach-sign --no-commit -b fluffypony v0.14.0
|
||||
```
|
||||
`./gitian-build.py --detach-sign --no-commit -b fluffypony v0.14.0`
|
||||
|
||||
To speed up the build, use `-j 5 -m 5000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 5000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values.
|
||||
|
||||
@@ -138,7 +108,7 @@ If all went well, this produces a number of (uncommited) `.assert` files in the
|
||||
|
||||
If you do detached, offline signing, you need to copy these uncommited changes to your host machine, where you can sign them. For example:
|
||||
|
||||
```bash
|
||||
```
|
||||
export NAME=fluffypony
|
||||
export VERSION=v0.14.0
|
||||
gpg --output $VERSION-linux/$NAME/monero-linux-$VERSION-build.assert.sig --detach-sign $VERSION-linux/$NAME/monero-linux-$VERSION-build.assert
|
||||
@@ -149,31 +119,15 @@ gpg --output $VERSION-win-unsigned/$NAME/monero-win-$VERSION-build.assert.sig --
|
||||
Make a pull request (both the `.assert` and `.assert.sig` files) to the
|
||||
[monero-project/gitian.sigs](https://github.com/monero-project/gitian.sigs/) repository:
|
||||
|
||||
```bash
|
||||
```
|
||||
git checkout -b v0.14.0
|
||||
git commit -S -a -m "Add $NAME v0.14.0"
|
||||
git push --set-upstream $NAME v0.14.0
|
||||
```
|
||||
|
||||
```bash
|
||||
gpg --detach-sign ${VERSION}-linux/${SIGNER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win-unsigned/${SIGNER}/monero-win-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/monero-osx-*-build.assert
|
||||
```
|
||||
|
||||
More Build Options
|
||||
------------------
|
||||
|
||||
You can choose your own remote and commit hash by running for example:
|
||||
```bash
|
||||
./gitian-build.py --detach-sign --no-commit --url https://github.com/moneromooo-monero/bitmonero -b moneromooo 1f5680c8db8f4cc7acc04a04c724b832003440fd
|
||||
```
|
||||
|
||||
Note that you won't be able to build commits authored before the gitian scripts
|
||||
were added. Gitian clones the source files from the given url, be sure to push
|
||||
to the remote you provide before building.
|
||||
To get all build options run:
|
||||
```bash
|
||||
./gitian-build.py --help
|
||||
gpg --detach-sign ${VERSION}-linux/${SIGNER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win-unsigned/${SIGNER}/monero-win-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/monero-osx-*-build.assert
|
||||
```
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ def main():
|
||||
parser.add_argument('-D', '--detach-sign', action='store_true', dest='detach_sign', help='Create the assert file for detached signing. Will not commit anything.')
|
||||
parser.add_argument('-n', '--no-commit', action='store_false', dest='commit_files', help='Do not commit anything to git')
|
||||
parser.add_argument('signer', help='GPG signer to sign each build assert file')
|
||||
parser.add_argument('version', help='Version number, commit, or branch to build.')
|
||||
parser.add_argument('version', help='Version number, commit, or branch to build. If building a commit or branch, the -c option must be specified')
|
||||
|
||||
args = parser.parse_args()
|
||||
workdir = os.getcwd()
|
||||
|
||||
@@ -137,7 +137,7 @@ script: |
|
||||
if [ -d "$EXTRA_INCLUDES" ]; then
|
||||
export HOST_ID_SALT="$EXTRA_INCLUDES"
|
||||
fi
|
||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" V=1
|
||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1
|
||||
unset HOST_ID_SALT
|
||||
done
|
||||
|
||||
|
||||
@@ -12,17 +12,21 @@ packages:
|
||||
- "git"
|
||||
- "pkg-config"
|
||||
- "autoconf"
|
||||
- "librsvg2-bin"
|
||||
- "libtiff-tools"
|
||||
- "libtool"
|
||||
- "automake"
|
||||
- "faketime"
|
||||
- "bsdmainutils"
|
||||
- "cmake"
|
||||
- "imagemagick"
|
||||
- "libcap-dev"
|
||||
- "libz-dev"
|
||||
- "libbz2-dev"
|
||||
- "python"
|
||||
- "python-dev"
|
||||
- "python-setuptools"
|
||||
- "fonts-tuffy"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
|
||||
@@ -108,7 +108,7 @@ script: |
|
||||
if [ -d "$EXTRA_INCLUDES" ]; then
|
||||
export HOST_ID_SALT="$EXTRA_INCLUDES"
|
||||
fi
|
||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" V=1
|
||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1
|
||||
unset HOST_ID_SALT
|
||||
done
|
||||
|
||||
|
||||
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
@@ -100,4 +100,3 @@ endif()
|
||||
|
||||
add_subdirectory(db_drivers)
|
||||
add_subdirectory(easylogging++)
|
||||
add_subdirectory(randomwow)
|
||||
|
||||
4
external/db_drivers/liblmdb/mdb.c
vendored
4
external/db_drivers/liblmdb/mdb.c
vendored
@@ -1742,8 +1742,6 @@ mdb_strerror(int err)
|
||||
NULL, err, 0, ptr, MSGSIZE, (va_list *)buf+MSGSIZE);
|
||||
return ptr;
|
||||
#else
|
||||
if (err < 0)
|
||||
return "Invalid error code";
|
||||
return strerror(err);
|
||||
#endif
|
||||
}
|
||||
@@ -9643,7 +9641,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
|
||||
* the split so the new page is emptier than the old page.
|
||||
* This yields better packing during sequential inserts.
|
||||
*/
|
||||
if (nkeys < 32 || nsize > pmax/16 || newindx >= nkeys) {
|
||||
if (nkeys < 20 || nsize > pmax/16 || newindx >= nkeys) {
|
||||
/* Find split point */
|
||||
psize = 0;
|
||||
if (newindx <= split_indx || newindx >= nkeys) {
|
||||
|
||||
4
external/easylogging++/CMakeLists.txt
vendored
4
external/easylogging++/CMakeLists.txt
vendored
@@ -33,7 +33,6 @@ project(easylogging CXX)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
find_package(Threads)
|
||||
find_package(Backtrace)
|
||||
|
||||
add_library(easylogging
|
||||
easylogging++.cc)
|
||||
@@ -42,8 +41,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
target_link_libraries(easylogging
|
||||
PRIVATE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${Backtrace_LIBRARIES})
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
# GUI/libwallet install target
|
||||
if (BUILD_GUI_DEPS)
|
||||
|
||||
48
external/easylogging++/easylogging++.cc
vendored
48
external/easylogging++/easylogging++.cc
vendored
@@ -1,16 +1,17 @@
|
||||
//
|
||||
// Bismillah ar-Rahmaan ar-Raheem
|
||||
//
|
||||
// Easylogging++ v9.96.7
|
||||
// Easylogging++ v9.96.5
|
||||
// Cross-platform logging library for C++ applications
|
||||
//
|
||||
// Copyright (c) 2012-2018 Zuhd Web Services
|
||||
// Copyright (c) 2012-2018 Muflihun Labs
|
||||
// Copyright (c) 2012-2018 @abumusamq
|
||||
//
|
||||
// This library is released under the MIT Licence.
|
||||
// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE
|
||||
// https://github.com/muflihun/easyloggingpp/blob/master/LICENSE
|
||||
//
|
||||
// https://zuhd.org
|
||||
// https://github.com/muflihun/easyloggingpp
|
||||
// https://muflihun.github.io/easyloggingpp
|
||||
// http://muflihun.com
|
||||
//
|
||||
|
||||
@@ -961,7 +962,7 @@ void Str::replaceFirstWithEscape(base::type::string_t& str, const base::type::st
|
||||
std::size_t foundAt = base::type::string_t::npos;
|
||||
while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
|
||||
if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) {
|
||||
str.erase(foundAt - 1, 1);
|
||||
str.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
|
||||
++foundAt;
|
||||
} else {
|
||||
str.replace(foundAt, replaceWhat.length(), replaceWith);
|
||||
@@ -1530,7 +1531,7 @@ void LogFormat::parseFromFormat(const base::type::string_t& userFormat) {
|
||||
if (hasFlag(flag)) {
|
||||
// If we already have flag we remove the escape chars so that '%%' is turned to '%'
|
||||
// even after specifier resolution - this is because we only replaceFirst specifier
|
||||
formatCopy.erase(foundAt - 1, 1);
|
||||
formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
|
||||
++foundAt;
|
||||
}
|
||||
} else {
|
||||
@@ -2205,26 +2206,20 @@ Storage::Storage(const LogBuilderPtr& defaultLogBuilder) :
|
||||
m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)),
|
||||
m_flags(ELPP_DEFAULT_LOGGING_FLAGS),
|
||||
m_vRegistry(new base::VRegistry(0, &m_flags)),
|
||||
|
||||
#if ELPP_ASYNC_LOGGING
|
||||
m_asyncLogQueue(new base::AsyncLogQueue()),
|
||||
m_asyncDispatchWorker(asyncDispatchWorker),
|
||||
#endif // ELPP_ASYNC_LOGGING
|
||||
|
||||
m_preRollOutCallback(base::defaultPreRollOutCallback) {
|
||||
// Register default logger
|
||||
m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId));
|
||||
// We register default logger anyway (worse case it's not going to register) just in case
|
||||
m_registeredLoggers->get("default");
|
||||
|
||||
#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||
// Register performance logger and reconfigure format
|
||||
Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId));
|
||||
m_registeredLoggers->get("performance");
|
||||
performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg"));
|
||||
performanceLogger->reconfigure();
|
||||
#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||
|
||||
#if defined(ELPP_SYSLOG)
|
||||
// Register syslog logger and reconfigure format
|
||||
Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId));
|
||||
@@ -2342,19 +2337,6 @@ base::threading::Mutex& LogDispatchCallback::fileHandle(const LogDispatchData* d
|
||||
namespace base {
|
||||
// DefaultLogDispatchCallback
|
||||
|
||||
const char* convertToChar(Level level) {
|
||||
// Do not use switch over strongly typed enums because Intel C++ compilers dont support them yet.
|
||||
if (level == Level::Global) return "G";
|
||||
if (level == Level::Debug) return "D";
|
||||
if (level == Level::Info) return "I";
|
||||
if (level == Level::Warning) return "W";
|
||||
if (level == Level::Error) return "E";
|
||||
if (level == Level::Fatal) return "F";
|
||||
if (level == Level::Verbose) return "V";
|
||||
if (level == Level::Trace) return "T";
|
||||
return "?";
|
||||
}
|
||||
|
||||
void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
|
||||
#if defined(ELPP_THREAD_SAFE)
|
||||
#if 0
|
||||
@@ -2363,15 +2345,11 @@ void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
|
||||
#endif
|
||||
#endif
|
||||
m_data = data;
|
||||
base::TypedConfigurations* tc = m_data->logMessage()->logger()->typedConfigurations();
|
||||
const base::LogFormat* logFormat = &tc->logFormat(m_data->logMessage()->level());
|
||||
dispatch(base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), &tc->subsecondPrecision(m_data->logMessage()->level()))
|
||||
+ "\t" + convertToChar(m_data->logMessage()->level()) + " " + m_data->logMessage()->message() + "\n",
|
||||
m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
||||
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
||||
m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog));
|
||||
}
|
||||
|
||||
void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLine, base::type::string_t&& logLine) {
|
||||
void DefaultLogDispatchCallback::dispatch(base::type::string_t&& logLine) {
|
||||
if (m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog) {
|
||||
if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
|
||||
base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(
|
||||
@@ -2398,8 +2376,8 @@ void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLine, base::
|
||||
if (m_data->dispatchAction() != base::DispatchAction::FileOnlyLog) {
|
||||
if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
|
||||
if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
|
||||
m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&rawLine, m_data->logMessage()->level());
|
||||
ELPP_COUT << ELPP_COUT_LINE(rawLine);
|
||||
m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level());
|
||||
ELPP_COUT << ELPP_COUT_LINE(logLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3301,11 +3279,11 @@ const std::string &Loggers::getFilenameCommonPrefix() {
|
||||
// VersionInfo
|
||||
|
||||
const std::string VersionInfo::version(void) {
|
||||
return std::string("9.96.7");
|
||||
return std::string("9.96.5");
|
||||
}
|
||||
/// @brief Release date of current version
|
||||
const std::string VersionInfo::releaseDate(void) {
|
||||
return std::string("24-11-2018 0728hrs");
|
||||
return std::string("07-09-2018 0950hrs");
|
||||
}
|
||||
|
||||
} // namespace el
|
||||
|
||||
15
external/easylogging++/easylogging++.h
vendored
15
external/easylogging++/easylogging++.h
vendored
@@ -1,16 +1,17 @@
|
||||
//
|
||||
// Bismillah ar-Rahmaan ar-Raheem
|
||||
//
|
||||
// Easylogging++ v9.96.7
|
||||
// Easylogging++ v9.96.5
|
||||
// Single-header only, cross-platform logging library for C++ applications
|
||||
//
|
||||
// Copyright (c) 2012-2018 Zuhd Web Services
|
||||
// Copyright (c) 2012-2018 Muflihun Labs
|
||||
// Copyright (c) 2012-2018 @abumusamq
|
||||
//
|
||||
// This library is released under the MIT Licence.
|
||||
// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE
|
||||
// https://github.com/muflihun/easyloggingpp/blob/master/LICENSE
|
||||
//
|
||||
// https://zuhd.org
|
||||
// https://github.com/muflihun/easyloggingpp
|
||||
// https://muflihun.github.io/easyloggingpp
|
||||
// http://muflihun.com
|
||||
//
|
||||
|
||||
@@ -757,12 +758,10 @@ static const char* kDefaultLoggerId = ELPP_DEFAULT_L
|
||||
static const char* kDefaultLoggerId = "default";
|
||||
#endif
|
||||
|
||||
#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||
#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
|
||||
static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
|
||||
#else
|
||||
static const char* kPerformanceLoggerId = "performance";
|
||||
#endif // ELPP_DEFAULT_PERFORMANCE_LOGGER
|
||||
#endif
|
||||
|
||||
#if defined(ELPP_SYSLOG)
|
||||
@@ -2777,7 +2776,7 @@ class DefaultLogDispatchCallback : public LogDispatchCallback {
|
||||
void handle(const LogDispatchData* data);
|
||||
private:
|
||||
const LogDispatchData* m_data;
|
||||
void dispatch(base::type::string_t&& rawLine, base::type::string_t&& logLine);
|
||||
void dispatch(base::type::string_t&& logLine);
|
||||
};
|
||||
#if ELPP_ASYNC_LOGGING
|
||||
class AsyncLogDispatchCallback : public LogDispatchCallback {
|
||||
@@ -3837,7 +3836,7 @@ class Helpers : base::StaticClass {
|
||||
return ELPP->hasCustomFormatSpecifier(formatSpecifier);
|
||||
}
|
||||
static inline void validateFileRolling(Logger* logger, Level level) {
|
||||
if (ELPP == nullptr || logger == nullptr) return;
|
||||
if (logger == nullptr) return;
|
||||
logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
|
||||
}
|
||||
};
|
||||
|
||||
1
external/randomwow
vendored
1
external/randomwow
vendored
Submodule external/randomwow deleted from 435a8382d8
2
external/trezor-common
vendored
2
external/trezor-common
vendored
Submodule external/trezor-common updated: cb238cb1f1...588f8e03f5
2
external/unbound
vendored
2
external/unbound
vendored
Submodule external/unbound updated: 0f6c0579d6...7f23967954
88
installers/build-cli-win.py
Normal file
88
installers/build-cli-win.py
Normal file
@@ -0,0 +1,88 @@
|
||||
#
|
||||
# This is a script for easily building the wownero cli installer in an automated build. Note
|
||||
# that it is also possible to build the installer by dropping the .nsi file on the NSIS GUI,
|
||||
# but that this will not work, as the script requires some defines, parsed from the wownero
|
||||
# version file, to be passed on the command line.
|
||||
#
|
||||
|
||||
import sys
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
#
|
||||
# Grab the dir of this .py
|
||||
#
|
||||
basedir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
#
|
||||
# Try to find version.cpp.in.
|
||||
#
|
||||
version_file = os.path.join('..', 'src', 'version.cpp.in')
|
||||
if not os.path.isfile(version_file):
|
||||
print('Version file not found: %s' % version_file)
|
||||
sys.exit(-1)
|
||||
|
||||
#
|
||||
# Try to parse version.cpp.in.
|
||||
#
|
||||
version_string = None
|
||||
release_name = None
|
||||
with open(version_file, 'r') as fp:
|
||||
version_prefix = '#define DEF_MONERO_VERSION "'
|
||||
release_prefix = '#define DEF_MONERO_RELEASE_NAME "'
|
||||
for line in fp:
|
||||
if line.startswith(version_prefix):
|
||||
version_string = line.replace(version_prefix, '')[:-2]
|
||||
elif line.startswith(release_prefix):
|
||||
release_name = line.replace(release_prefix, '')[:-2]
|
||||
|
||||
if not version_string:
|
||||
print('Failed to parse version from: %s' % version_file)
|
||||
sys.exit(-1)
|
||||
|
||||
if not release_name:
|
||||
print('Failed to parse release name from: %s' % version_file)
|
||||
sys.exit(-1)
|
||||
|
||||
#
|
||||
# Check that we got an expected version format.
|
||||
#
|
||||
version_parts = version_string.split('.')
|
||||
if len(version_parts) != 4:
|
||||
print('Invalid version string: %s' % version_string)
|
||||
sys.exit(-1)
|
||||
|
||||
#
|
||||
# Try to find makensis.
|
||||
#
|
||||
makensis = 'makensis.exe'
|
||||
if not os.path.isfile(makensis):
|
||||
for dir in os.environ['PATH'].split(';'):
|
||||
test = os.path.join(dir, makensis)
|
||||
if os.path.isfile(test):
|
||||
makensis = test
|
||||
break
|
||||
|
||||
if not os.path.isfile(makensis):
|
||||
print('Failed to find makensis.exe')
|
||||
sys.exit(-1)
|
||||
|
||||
#
|
||||
# Build & run makensis command line.
|
||||
#
|
||||
cmd = '"%s"' % makensis
|
||||
cmd += ' /V4'
|
||||
cmd += ' /DVERSION_MAJOR=%s' % version_parts[0]
|
||||
cmd += ' /DVERSION_MINOR=%s' % version_parts[1]
|
||||
cmd += ' /DVERSION_BUILD=%s' % version_parts[2]
|
||||
cmd += ' /DVERSION_REVISION=%s' % version_parts[3]
|
||||
cmd += ' /DRELEASE_NAME="%s"' % release_name
|
||||
cmd += ' "%s"' % os.path.join(basedir, 'cli-win', 'installer.nsi')
|
||||
|
||||
print("Calling makensis: %s" % cmd)
|
||||
|
||||
subprocess.call(cmd)
|
||||
|
||||
BIN
installers/cli-win/app.ico
Normal file
BIN
installers/cli-win/app.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
BIN
installers/cli-win/header.bmp
Normal file
BIN
installers/cli-win/header.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
262
installers/cli-win/installer.nsi
Normal file
262
installers/cli-win/installer.nsi
Normal file
@@ -0,0 +1,262 @@
|
||||
;-----------------------------------------------------------------------------------------
|
||||
; File: Wownero CLI NSIS installer
|
||||
; Author: 0x000090
|
||||
; Date: 1 Dec 2018
|
||||
; License: WTFPL
|
||||
;-----------------------------------------------------------------------------------------
|
||||
;
|
||||
; DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
; Version 2, December 2004
|
||||
;
|
||||
; Copyright (C) 2018 Wownero Inc., a Monero Enterprise Alliance partner company
|
||||
;
|
||||
; DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
; TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
;
|
||||
; 0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
;
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!include 'MUI2.nsh'
|
||||
!include 'TextFunc.nsh'
|
||||
!include 'WordFunc.nsh'
|
||||
!include 'Sections.nsh'
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!ifndef VERSION_MAJOR
|
||||
!warning 'VERSION_MAJOR not defined!'
|
||||
Quit
|
||||
!endif
|
||||
|
||||
!ifndef VERSION_MINOR
|
||||
!warning 'VERSION_MINOR not defined!'
|
||||
Quit
|
||||
!endif
|
||||
|
||||
!ifndef VERSION_BUILD
|
||||
!warning 'VERSION_BUILD not defined!'
|
||||
Quit
|
||||
!endif
|
||||
|
||||
!ifndef VERSION_REVISION
|
||||
!warning 'VERSION_REVISION not defined!'
|
||||
Quit
|
||||
!endif
|
||||
|
||||
!ifndef RELEASE_NAME
|
||||
!warning 'RELEASE_NAME not defined!'
|
||||
Quit
|
||||
!endif
|
||||
|
||||
!define VERSION_SHORT '${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_BUILD}'
|
||||
!define VERSION_LONG '${VERSION_SHORT}.${VERSION_REVISION}'
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!define PROJECT_NAME 'Wownero'
|
||||
!define PRODUCT_NAME 'Wownero CLI'
|
||||
!define COMPANY_NAME 'Wownero Inc.'
|
||||
!define EXE_BASENAME 'wownero'
|
||||
!define HELP_URL 'http://wownero.org/#community'
|
||||
!define ABOUT_URL 'http://wownero.org/#about'
|
||||
!define SOURCE_DIR '..\..\build\release\bin'
|
||||
!define TARGET_DIR '..\..\build\installers'
|
||||
!define TARGET_PATH '${TARGET_DIR}\Wownero-CLI-${VERSION_LONG}-win.exe'
|
||||
!define INSTALL_SUBDIR 'cli'
|
||||
!define INSTALL_SIZE 181000
|
||||
!define UNINSTALLER_NAME 'uninstall.exe'
|
||||
!define REG_BASE 'Software\Microsoft\Windows\CurrentVersion\Uninstall'
|
||||
!define REG_KEY '${REG_BASE}\{E114584F-4E1B-4B2D-8B1C-69A188025E98}'
|
||||
!define /date CURRENT_YEAR '%Y'
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!system 'if not exist "${TARGET_DIR}" md "${TARGET_DIR}"'
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Name '${PRODUCT_NAME}'
|
||||
OutFile '${TARGET_PATH}'
|
||||
BrandingText '${PRODUCT_NAME} ${VERSION_LONG} "${RELEASE_NAME}"'
|
||||
CRCCheck force
|
||||
RequestExecutionLevel admin
|
||||
InstallDir "$PROGRAMFILES64\${PROJECT_NAME}\${INSTALL_SUBDIR}"
|
||||
ShowInstDetails show
|
||||
ShowUninstDetails show
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
VIAddVersionKey 'CompanyName' '${COMPANY_NAME}'
|
||||
VIAddVersionKey 'ProductName' '${PRODUCT_NAME}'
|
||||
VIAddVersionKey 'FileDescription' '${PRODUCT_NAME}'
|
||||
VIAddVersionKey 'LegalCopyright' 'Copyright (c) ${CURRENT_YEAR}, ${COMPANY_NAME}'
|
||||
VIAddVersionKey 'FileVersion' '${VERSION_SHORT}'
|
||||
VIProductVersion '${VERSION_LONG}'
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_UNABORTWARNING
|
||||
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
|
||||
|
||||
!define MUI_ICON "app.ico"
|
||||
!define MUI_UNICON "app.ico"
|
||||
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_RIGHT
|
||||
!define MUI_HEADERIMAGE_BITMAP "header.bmp"
|
||||
!define MUI_HEADERIMAGE_UNBITMAP "header.bmp"
|
||||
!define MUI_HEADERIMAGE_BITMAP_NOSTRETCH
|
||||
!define MUI_HEADERIMAGE_UNBITMAP_NOSTRETCH
|
||||
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "welcome.bmp"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "welcome.bmp"
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH
|
||||
!define MUI_UNWELCOMEFINISHPAGE_UNBITMAP_NOSTRETCH
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_UNPAGE_WELCOME
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Function VerifyUserIsAdmin
|
||||
UserInfo::GetAccountType
|
||||
Pop $0
|
||||
${If} $0 != "admin"
|
||||
MessageBox MB_ICONSTOP "Admin permissions required, please use right-click > Run as Administrator."
|
||||
SetErrorLevel 740 ; ERROR_ELEVATION_REQUIRED
|
||||
Quit
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
Function .onInit
|
||||
Call VerifyUserIsAdmin
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
FunctionEnd
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
!macro RemoveFile file
|
||||
Push $0
|
||||
${TrimNewLines} '${file}' $0
|
||||
SetDetailsPrint both
|
||||
${If} ${FileExists} '$0'
|
||||
DetailPrint 'Deleting file $0'
|
||||
SetDetailsPrint textonly
|
||||
Delete "$0"
|
||||
${Else}
|
||||
DetailPrint 'File not found: $0'
|
||||
${Endif}
|
||||
SetDetailsPrint lastused
|
||||
Pop $0
|
||||
!macroend
|
||||
|
||||
!macro RemoveDir dir
|
||||
Push $0
|
||||
${TrimNewLines} '${dir}' $0
|
||||
SetDetailsPrint both
|
||||
${If} ${FileExists} '$0'
|
||||
DetailPrint 'Deleting directory $0'
|
||||
SetDetailsPrint textonly
|
||||
RmDir /r "$0"
|
||||
${Else}
|
||||
DetailPrint 'Directory not found: $0'
|
||||
${Endif}
|
||||
SetDetailsPrint lastused
|
||||
Pop $0
|
||||
!macroend
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Function WriteFiles
|
||||
DetailPrint 'Installing application files...'
|
||||
SetDetailsPrint both
|
||||
SetOutPath '$INSTDIR'
|
||||
File 'app.ico'
|
||||
|
||||
;
|
||||
; Add here whatever else you want to be included:
|
||||
;
|
||||
File '${SOURCE_DIR}\${EXE_BASENAME}d.exe'
|
||||
File '${SOURCE_DIR}\${EXE_BASENAME}-wallet-cli.exe'
|
||||
File '${SOURCE_DIR}\${EXE_BASENAME}-wallet-rpc.exe'
|
||||
File '${SOURCE_DIR}\${EXE_BASENAME}-gen-trusted-multisig.exe'
|
||||
|
||||
;
|
||||
; NOTE: you can also add all files in a dir, like this:
|
||||
;
|
||||
;File /r '${SOURCE_DIR}\*.*'
|
||||
|
||||
SetDetailsPrint lastused
|
||||
DetailPrint 'Writing uninstaller...'
|
||||
WriteUninstaller '$INSTDIR\${UNINSTALLER_NAME}'
|
||||
FunctionEnd
|
||||
|
||||
Function un.WriteFiles
|
||||
DetailPrint 'Removing application files...'
|
||||
!insertmacro RemoveDir '$INSTDIR'
|
||||
FunctionEnd
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Function WriteShortcuts
|
||||
DetailPrint 'Creating Desktop shortcuts...'
|
||||
CreateShortCut '$DESKTOP\${PRODUCT_NAME} Wallet.lnk' '$INSTDIR\${EXE_BASENAME}-wallet-cli.exe' '' '$INSTDIR\app.ico'
|
||||
CreateShortCut '$DESKTOP\${PRODUCT_NAME} Daemon.lnk' '$INSTDIR\${EXE_BASENAME}d.exe' '' '$INSTDIR\app.ico'
|
||||
DetailPrint 'Creating Start Menu shortcuts...'
|
||||
CreateDirectory '$SMPROGRAMS\${COMPANY_NAME}\${PRODUCT_NAME}'
|
||||
CreateShortCut '$SMPROGRAMS\${COMPANY_NAME}\${PRODUCT_NAME}\${PRODUCT_NAME} Wallet.lnk' '$INSTDIR\${EXE_BASENAME}-wallet-cli.exe' '' '$INSTDIR\app.ico'
|
||||
CreateShortCut '$SMPROGRAMS\${COMPANY_NAME}\${PRODUCT_NAME}\${PRODUCT_NAME} Daemon.lnk' '$INSTDIR\${EXE_BASENAME}d.exe' '' '$INSTDIR\app.ico'
|
||||
CreateShortCut '$SMPROGRAMS\${COMPANY_NAME}\${PRODUCT_NAME}\Uninstall ${PRODUCT_NAME}.lnk' '$INSTDIR\${UNINSTALLER_NAME}' '' '$INSTDIR\app.ico'
|
||||
FunctionEnd
|
||||
|
||||
Function un.WriteShortcuts
|
||||
DetailPrint 'Removing Desktop shortcuts...'
|
||||
!insertmacro RemoveFile '$DESKTOP\${PRODUCT_NAME} Daemon.lnk'
|
||||
!insertmacro RemoveFile '$DESKTOP\${PRODUCT_NAME} Wallet.lnk'
|
||||
DetailPrint 'Removing Start Menu shortcuts...'
|
||||
!insertmacro RemoveDir '$SMPROGRAMS\${COMPANY_NAME}\${PRODUCT_NAME}'
|
||||
FunctionEnd
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Function WriteUninstaller
|
||||
DetailPrint 'Registering ${PRODUCT_NAME} ${VERSION_SHORT}'
|
||||
WriteRegDWORD HKLM '${REG_KEY}' 'VersionMajor' ${VERSION_MAJOR}
|
||||
WriteRegDWORD HKLM '${REG_KEY}' 'VersionMinor' ${VERSION_MINOR}
|
||||
WriteRegDWORD HKLM '${REG_KEY}' 'EstimatedSize' ${INSTALL_SIZE}
|
||||
WriteRegDWORD HKLM '${REG_KEY}' 'NoModify' 1
|
||||
WriteRegDWORD HKLM '${REG_KEY}' 'NoRepair' 1
|
||||
WriteRegStr HKLM '${REG_KEY}' 'Contact' '${COMPANY_NAME}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'Publisher' '${COMPANY_NAME}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'HelpLink' '${HELP_URL}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'URLInfoAbout' '${ABOUT_URL}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'DisplayVersion' '${VERSION_SHORT}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'Comments' '${PRODUCT_NAME}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'DisplayName' '${PRODUCT_NAME} ${VERSION_SHORT}'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'InstallLocation' '"$INSTDIR"'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'DisplayIcon' '"$INSTDIR\app.ico"'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'UninstallString' '"$INSTDIR\${UNINSTALLER_NAME}"'
|
||||
WriteRegStr HKLM '${REG_KEY}' 'QuietUninstallString' '"$INSTDIR\${UNINSTALLER_NAME}" /S'
|
||||
FunctionEnd
|
||||
|
||||
Function un.WriteUninstaller
|
||||
DetailPrint 'Unregistering ${PRODUCT_NAME} ${VERSION_SHORT}...'
|
||||
DeleteRegKey HKLM '${REG_KEY}'
|
||||
FunctionEnd
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Section "${PRODUCT_NAME} ${VERSION_SHORT}"
|
||||
Call WriteFiles
|
||||
Call WriteShortcuts
|
||||
Call WriteUninstaller
|
||||
SectionEnd
|
||||
|
||||
;-----------------------------------------------------------------------------------------
|
||||
Section "Uninstall"
|
||||
Call un.WriteFiles
|
||||
Call un.WriteShortcuts
|
||||
Call un.WriteUninstaller
|
||||
SectionEnd
|
||||
|
||||
BIN
installers/cli-win/welcome.bmp
Normal file
BIN
installers/cli-win/welcome.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
31
installers/readme.txt
Normal file
31
installers/readme.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
Installer notes
|
||||
|
||||
So, at this point I just have one installer, for the cli, on windows. What do you need
|
||||
to know ..
|
||||
|
||||
1. It uses NSIS, and expects to find makensis.exe on your PATH.
|
||||
|
||||
2. It expects built products to be found at:
|
||||
|
||||
wownero/build/release/bin
|
||||
|
||||
3. It currently includes the daemon, wallet, rpc, and gen-trusted-multisig. I note that
|
||||
releases on the wownero github have had different files (static libs, pthreads dll)
|
||||
than I end up with in my /bin dir when I build, so you may or may not need to change
|
||||
which files you include. At any rate, it is easy to do, in the WriteFiles function
|
||||
in installer.nsi.
|
||||
|
||||
4. Provided everything is ok, it should be as simple as executing build-cli-win.py; built
|
||||
installer, versioned according to src/version.cpp.in, will be depostied here:
|
||||
|
||||
wownero/build/installers/Wownero-CLI-<version>-win.exe
|
||||
|
||||
5. The installer includes an uninstaller, shortcuts on desktop & start menu, and it
|
||||
registers itself with windows, so it shows up as expected in programs & features.
|
||||
|
||||
6. I have tried to keep the installer script pretty generic, so it can be reused later,
|
||||
for gui, or whatever. It installs to a <program files>/Wownero/cli subdirectory, so
|
||||
that other applications can eventually be installed alongside. NOTE: if you copy the
|
||||
installer.nsi file to use for another project, you will need to make a new GUID for
|
||||
it, and put it in the REG_KEY define.
|
||||
|
||||
@@ -109,9 +109,7 @@ add_subdirectory(ringct)
|
||||
add_subdirectory(checkpoints)
|
||||
add_subdirectory(cryptonote_basic)
|
||||
add_subdirectory(cryptonote_core)
|
||||
add_subdirectory(lmdb)
|
||||
add_subdirectory(multisig)
|
||||
add_subdirectory(net)
|
||||
if(NOT IOS)
|
||||
add_subdirectory(blockchain_db)
|
||||
endif()
|
||||
|
||||
@@ -1654,6 +1654,36 @@ tx_out_index BlockchainBDB::get_output_tx_and_index(const uint64_t& amount, cons
|
||||
return indices[0];
|
||||
}
|
||||
|
||||
std::vector<uint64_t> BlockchainBDB::get_tx_output_indices(const crypto::hash& h) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainBDB::" << __func__);
|
||||
check_open();
|
||||
std::vector<uint64_t> index_vec;
|
||||
|
||||
bdb_cur cur(DB_DEFAULT_TX, m_tx_outputs);
|
||||
|
||||
Dbt_copy<crypto::hash> k(h);
|
||||
Dbt_copy<uint32_t> v;
|
||||
auto result = cur->get(&k, &v, DB_SET);
|
||||
if (result == DB_NOTFOUND)
|
||||
throw1(OUTPUT_DNE("Attempting to get an output by tx hash and tx index, but output not found"));
|
||||
else if (result)
|
||||
throw0(DB_ERROR("DB error attempting to get an output"));
|
||||
|
||||
db_recno_t num_elems = 0;
|
||||
cur->count(&num_elems, 0);
|
||||
|
||||
for (uint64_t i = 0; i < num_elems; ++i)
|
||||
{
|
||||
index_vec.push_back(v);
|
||||
cur->get(&k, &v, DB_NEXT_DUP);
|
||||
}
|
||||
|
||||
cur.close();
|
||||
|
||||
return index_vec;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> BlockchainBDB::get_tx_amount_output_indices(const crypto::hash& h) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainBDB::" << __func__);
|
||||
|
||||
@@ -312,6 +312,7 @@ public:
|
||||
virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index);
|
||||
virtual void get_output_tx_and_index(const uint64_t& amount, const std::vector<uint64_t> &offsets, std::vector<tx_out_index> &indices);
|
||||
|
||||
virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h) const;
|
||||
virtual std::vector<uint64_t> get_tx_amount_output_indices(const crypto::hash& h) const;
|
||||
|
||||
virtual bool has_key_image(const crypto::key_image& img) const;
|
||||
|
||||
@@ -121,10 +121,8 @@ void BlockchainDB::pop_block()
|
||||
pop_block(blk, txs);
|
||||
}
|
||||
|
||||
void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& txp, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
|
||||
void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
|
||||
{
|
||||
const transaction &tx = txp.first;
|
||||
|
||||
bool miner_tx = false;
|
||||
crypto::hash tx_hash, tx_prunable_hash;
|
||||
if (!tx_hash_ptr)
|
||||
@@ -140,7 +138,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
||||
if (tx.version >= 2)
|
||||
{
|
||||
if (!tx_prunable_hash_ptr)
|
||||
tx_prunable_hash = get_transaction_prunable_hash(tx, &txp.second);
|
||||
tx_prunable_hash = get_transaction_prunable_hash(tx);
|
||||
else
|
||||
tx_prunable_hash = *tx_prunable_hash_ptr;
|
||||
}
|
||||
@@ -170,7 +168,7 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t tx_id = add_transaction_data(blk_hash, txp, tx_hash, tx_prunable_hash);
|
||||
uint64_t tx_id = add_transaction_data(blk_hash, tx, tx_hash, tx_prunable_hash);
|
||||
|
||||
std::vector<uint64_t> amount_output_indices(tx.vout.size());
|
||||
|
||||
@@ -197,20 +195,19 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
|
||||
add_tx_amount_output_indices(tx_id, amount_output_indices);
|
||||
}
|
||||
|
||||
uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
||||
uint64_t BlockchainDB::add_block( const block& blk
|
||||
, size_t block_weight
|
||||
, uint64_t long_term_block_weight
|
||||
, const difficulty_type& cumulative_difficulty
|
||||
, const uint64_t& coins_generated
|
||||
, const std::vector<std::pair<transaction, blobdata>>& txs
|
||||
, const std::vector<transaction>& txs
|
||||
)
|
||||
{
|
||||
const block &blk = blck.first;
|
||||
|
||||
// sanity
|
||||
if (blk.tx_hashes.size() != txs.size())
|
||||
throw std::runtime_error("Inconsistent tx/hashes sizes");
|
||||
|
||||
block_txn_start(false);
|
||||
|
||||
TIME_MEASURE_START(time1);
|
||||
crypto::hash blk_hash = get_block_hash(blk);
|
||||
TIME_MEASURE_FINISH(time1);
|
||||
@@ -223,16 +220,16 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
||||
time1 = epee::misc_utils::get_tick_count();
|
||||
|
||||
uint64_t num_rct_outs = 0;
|
||||
add_transaction(blk_hash, std::make_pair(blk.miner_tx, tx_to_blob(blk.miner_tx)));
|
||||
add_transaction(blk_hash, blk.miner_tx);
|
||||
if (blk.miner_tx.version == 2)
|
||||
num_rct_outs += blk.miner_tx.vout.size();
|
||||
int tx_i = 0;
|
||||
crypto::hash tx_hash = crypto::null_hash;
|
||||
for (const std::pair<transaction, blobdata>& tx : txs)
|
||||
for (const transaction& tx : txs)
|
||||
{
|
||||
tx_hash = blk.tx_hashes[tx_i];
|
||||
add_transaction(blk_hash, tx, &tx_hash);
|
||||
for (const auto &vout: tx.first.vout)
|
||||
for (const auto &vout: tx.vout)
|
||||
{
|
||||
if (vout.amount == 0)
|
||||
++num_rct_outs;
|
||||
@@ -244,12 +241,14 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
||||
|
||||
// call out to subclass implementation to add the block & metadata
|
||||
time1 = epee::misc_utils::get_tick_count();
|
||||
add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash);
|
||||
add_block(blk, block_weight, cumulative_difficulty, coins_generated, num_rct_outs, blk_hash);
|
||||
TIME_MEASURE_FINISH(time1);
|
||||
time_add_block1 += time1;
|
||||
|
||||
m_hardfork->add(blk, prev_height);
|
||||
|
||||
block_txn_stop();
|
||||
|
||||
++num_calls;
|
||||
|
||||
return prev_height;
|
||||
@@ -268,10 +267,7 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)
|
||||
|
||||
for (const auto& h : boost::adaptors::reverse(blk.tx_hashes))
|
||||
{
|
||||
cryptonote::transaction tx;
|
||||
if (!get_tx(h, tx) && !get_pruned_tx(h, tx))
|
||||
throw DB_ERROR("Failed to get pruned or unpruned transaction from the db");
|
||||
txs.push_back(std::move(tx));
|
||||
txs.push_back(get_tx(h));
|
||||
remove_transaction(h);
|
||||
}
|
||||
remove_transaction(get_transaction_hash(blk.miner_tx));
|
||||
@@ -284,7 +280,7 @@ bool BlockchainDB::is_open() const
|
||||
|
||||
void BlockchainDB::remove_transaction(const crypto::hash& tx_hash)
|
||||
{
|
||||
transaction tx = get_pruned_tx(tx_hash);
|
||||
transaction tx = get_tx(tx_hash);
|
||||
|
||||
for (const txin_v& tx_input : tx.vin)
|
||||
{
|
||||
@@ -329,17 +325,6 @@ bool BlockchainDB::get_tx(const crypto::hash& h, cryptonote::transaction &tx) co
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockchainDB::get_pruned_tx(const crypto::hash& h, cryptonote::transaction &tx) const
|
||||
{
|
||||
blobdata bd;
|
||||
if (!get_pruned_tx_blob(h, bd))
|
||||
return false;
|
||||
if (!parse_and_validate_tx_base_from_blob(bd, tx))
|
||||
throw DB_ERROR("Failed to parse transaction base from blob retrieved from the db");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
transaction BlockchainDB::get_tx(const crypto::hash& h) const
|
||||
{
|
||||
transaction tx;
|
||||
@@ -348,14 +333,6 @@ transaction BlockchainDB::get_tx(const crypto::hash& h) const
|
||||
return tx;
|
||||
}
|
||||
|
||||
transaction BlockchainDB::get_pruned_tx(const crypto::hash& h) const
|
||||
{
|
||||
transaction tx;
|
||||
if (!get_pruned_tx(h, tx))
|
||||
throw TX_DNE(std::string("pruned tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str());
|
||||
return tx;
|
||||
}
|
||||
|
||||
void BlockchainDB::reset_stats()
|
||||
{
|
||||
num_calls = 0;
|
||||
|
||||
@@ -129,15 +129,6 @@ struct tx_data_t
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct alt_block_data_t
|
||||
{
|
||||
uint64_t height;
|
||||
uint64_t cumulative_weight;
|
||||
uint64_t cumulative_difficulty_low;
|
||||
uint64_t cumulative_difficulty_high;
|
||||
uint64_t already_generated_coins;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief a struct containing txpool per transaction metadata
|
||||
*/
|
||||
@@ -367,14 +358,12 @@ private:
|
||||
*
|
||||
* @param blk the block to be added
|
||||
* @param block_weight the weight of the block (transactions and all)
|
||||
* @param long_term_block_weight the long term block weight of the block (transactions and all)
|
||||
* @param cumulative_difficulty the accumulated difficulty after this block
|
||||
* @param coins_generated the number of coins generated total after this block
|
||||
* @param blk_hash the hash of the block
|
||||
*/
|
||||
virtual void add_block( const block& blk
|
||||
, size_t block_weight
|
||||
, uint64_t long_term_block_weight
|
||||
, const difficulty_type& cumulative_difficulty
|
||||
, const uint64_t& coins_generated
|
||||
, uint64_t num_rct_outs
|
||||
@@ -386,7 +375,7 @@ private:
|
||||
*
|
||||
* The subclass implementing this will remove the block data from the top
|
||||
* block in the chain. The data to be removed is that which was added in
|
||||
* BlockchainDB::add_block(const block& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const crypto::hash& blk_hash)
|
||||
* BlockchainDB::add_block(const block& blk, size_t block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const crypto::hash& blk_hash)
|
||||
*
|
||||
* If any of this cannot be done, the subclass should throw the corresponding
|
||||
* subclass of DB_EXCEPTION
|
||||
@@ -413,7 +402,7 @@ private:
|
||||
* @param tx_prunable_hash the hash of the prunable part of the transaction
|
||||
* @return the transaction ID
|
||||
*/
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) = 0;
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) = 0;
|
||||
|
||||
/**
|
||||
* @brief remove data about a transaction
|
||||
@@ -541,7 +530,7 @@ protected:
|
||||
* @param tx_hash_ptr the hash of the transaction, if already calculated
|
||||
* @param tx_prunable_hash_ptr the hash of the prunable part of the transaction, if already calculated
|
||||
*/
|
||||
void add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);
|
||||
void add_transaction(const crypto::hash& blk_hash, const transaction& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);
|
||||
|
||||
mutable uint64_t time_tx_exists = 0; //!< a performance metric
|
||||
uint64_t time_commit1 = 0; //!< a performance metric
|
||||
@@ -762,21 +751,6 @@ public:
|
||||
*/
|
||||
virtual void batch_stop() = 0;
|
||||
|
||||
/**
|
||||
* @brief aborts a batch transaction
|
||||
*
|
||||
* If the subclass implements batching, this function should abort the
|
||||
* batch it is currently on.
|
||||
*
|
||||
* If no batch is in-progress, this function should throw a DB_ERROR.
|
||||
* This exception may change in the future if it is deemed necessary to
|
||||
* have a more granular exception type for this scenario.
|
||||
*
|
||||
* If any of this cannot be done, the subclass should throw the corresponding
|
||||
* subclass of DB_EXCEPTION
|
||||
*/
|
||||
virtual void batch_abort() = 0;
|
||||
|
||||
/**
|
||||
* @brief sets whether or not to batch transactions
|
||||
*
|
||||
@@ -794,12 +768,9 @@ public:
|
||||
*/
|
||||
virtual void set_batch_transactions(bool) = 0;
|
||||
|
||||
virtual void block_wtxn_start() = 0;
|
||||
virtual void block_wtxn_stop() = 0;
|
||||
virtual void block_wtxn_abort() = 0;
|
||||
virtual bool block_rtxn_start() const = 0;
|
||||
virtual void block_rtxn_stop() const = 0;
|
||||
virtual void block_rtxn_abort() const = 0;
|
||||
virtual void block_txn_start(bool readonly=false) = 0;
|
||||
virtual void block_txn_stop() = 0;
|
||||
virtual void block_txn_abort() = 0;
|
||||
|
||||
virtual void set_hard_fork(HardFork* hf);
|
||||
|
||||
@@ -818,19 +789,17 @@ public:
|
||||
*
|
||||
* @param blk the block to be added
|
||||
* @param block_weight the size of the block (transactions and all)
|
||||
* @param long_term_block_weight the long term weight of the block (transactions and all)
|
||||
* @param cumulative_difficulty the accumulated difficulty after this block
|
||||
* @param coins_generated the number of coins generated total after this block
|
||||
* @param txs the transactions in the block
|
||||
*
|
||||
* @return the height of the chain post-addition
|
||||
*/
|
||||
virtual uint64_t add_block( const std::pair<block, blobdata>& blk
|
||||
virtual uint64_t add_block( const block& blk
|
||||
, size_t block_weight
|
||||
, uint64_t long_term_block_weight
|
||||
, const difficulty_type& cumulative_difficulty
|
||||
, const uint64_t& coins_generated
|
||||
, const std::vector<std::pair<transaction, blobdata>>& txs
|
||||
, const std::vector<transaction>& txs
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -973,17 +942,6 @@ public:
|
||||
*/
|
||||
virtual size_t get_block_weight(const uint64_t& height) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch the last N blocks' weights
|
||||
*
|
||||
* If there are fewer than N blocks, the returned array will be smaller than N
|
||||
*
|
||||
* @param count the number of blocks requested
|
||||
*
|
||||
* @return the weights
|
||||
*/
|
||||
virtual std::vector<uint64_t> get_block_weights(uint64_t start_height, size_t count) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch a block's cumulative difficulty
|
||||
*
|
||||
@@ -1026,28 +984,6 @@ public:
|
||||
*/
|
||||
virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch a block's long term weight
|
||||
*
|
||||
* If the block does not exist, the subclass should throw BLOCK_DNE
|
||||
*
|
||||
* @param height the height requested
|
||||
*
|
||||
* @return the long term weight
|
||||
*/
|
||||
virtual uint64_t get_block_long_term_weight(const uint64_t& height) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch the last N blocks' long term weights
|
||||
*
|
||||
* If there are fewer than N blocks, the returned array will be smaller than N
|
||||
*
|
||||
* @param count the number of blocks requested
|
||||
*
|
||||
* @return the weights
|
||||
*/
|
||||
virtual std::vector<uint64_t> get_long_term_block_weights(uint64_t start_height, size_t count) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch a block's hash
|
||||
*
|
||||
@@ -1101,11 +1037,9 @@ public:
|
||||
*
|
||||
* The subclass should return the hash of the most recent block
|
||||
*
|
||||
* @param block_height if non NULL, returns the height of that block (ie, the blockchain height minus 1)
|
||||
*
|
||||
* @return the top block's hash
|
||||
*/
|
||||
virtual crypto::hash top_block_hash(uint64_t *block_height = NULL) const = 0;
|
||||
virtual crypto::hash top_block_hash() const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetch the top block
|
||||
@@ -1191,17 +1125,6 @@ public:
|
||||
*/
|
||||
virtual transaction get_tx(const crypto::hash& h) const;
|
||||
|
||||
/**
|
||||
* @brief fetches the transaction base with the given hash
|
||||
*
|
||||
* If the transaction does not exist, the subclass should throw TX_DNE.
|
||||
*
|
||||
* @param h the hash to look for
|
||||
*
|
||||
* @return the transaction with the given hash
|
||||
*/
|
||||
virtual transaction get_pruned_tx(const crypto::hash& h) const;
|
||||
|
||||
/**
|
||||
* @brief fetches the transaction with the given hash
|
||||
*
|
||||
@@ -1213,17 +1136,6 @@ public:
|
||||
*/
|
||||
virtual bool get_tx(const crypto::hash& h, transaction &tx) const;
|
||||
|
||||
/**
|
||||
* @brief fetches the transaction base with the given hash
|
||||
*
|
||||
* If the transaction does not exist, the subclass should return false.
|
||||
*
|
||||
* @param h the hash to look for
|
||||
*
|
||||
* @return true iff the transaction was found
|
||||
*/
|
||||
virtual bool get_pruned_tx(const crypto::hash& h, transaction &tx) const;
|
||||
|
||||
/**
|
||||
* @brief fetches the transaction blob with the given hash
|
||||
*
|
||||
@@ -1252,21 +1164,6 @@ public:
|
||||
*/
|
||||
virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches the prunable transaction blob with the given hash
|
||||
*
|
||||
* The subclass should return the prunable transaction stored which has the given
|
||||
* hash.
|
||||
*
|
||||
* If the transaction does not exist, or if we do not have that prunable data,
|
||||
* the subclass should return false.
|
||||
*
|
||||
* @param h the hash to look for
|
||||
*
|
||||
* @return true iff the transaction was found and we have its prunable data
|
||||
*/
|
||||
virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0;
|
||||
|
||||
/**
|
||||
* @brief fetches the prunable transaction hash
|
||||
*
|
||||
@@ -1515,82 +1412,6 @@ public:
|
||||
*/
|
||||
virtual void prune_outputs(uint64_t amount) = 0;
|
||||
|
||||
/**
|
||||
* @brief get the blockchain pruning seed
|
||||
* @return the blockchain pruning seed
|
||||
*/
|
||||
virtual uint32_t get_blockchain_pruning_seed() const = 0;
|
||||
|
||||
/**
|
||||
* @brief prunes the blockchain
|
||||
* @param pruning_seed the seed to use, 0 for default (highly recommended)
|
||||
* @return success iff true
|
||||
*/
|
||||
virtual bool prune_blockchain(uint32_t pruning_seed = 0) = 0;
|
||||
|
||||
/**
|
||||
* @brief prunes recent blockchain changes as needed, iff pruning is enabled
|
||||
* @return success iff true
|
||||
*/
|
||||
virtual bool update_pruning() = 0;
|
||||
|
||||
/**
|
||||
* @brief checks pruning was done correctly, iff enabled
|
||||
* @return success iff true
|
||||
*/
|
||||
virtual bool check_pruning() = 0;
|
||||
|
||||
/**
|
||||
* @brief get the max block size
|
||||
*/
|
||||
virtual uint64_t get_max_block_size() = 0;
|
||||
|
||||
/**
|
||||
* @brief add a new max block size
|
||||
*
|
||||
* The max block size will be the maximum of sz and the current block size
|
||||
*
|
||||
* @param: sz the block size
|
||||
*/
|
||||
virtual void add_max_block_size(uint64_t sz) = 0;
|
||||
|
||||
/**
|
||||
* @brief add a new alternative block
|
||||
*
|
||||
* @param: blkid the block hash
|
||||
* @param: data: the metadata for the block
|
||||
* @param: blob: the block's blob
|
||||
*/
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata &blob) = 0;
|
||||
|
||||
/**
|
||||
* @brief get an alternative block by hash
|
||||
*
|
||||
* @param: blkid the block hash
|
||||
* @param: data: the metadata for the block
|
||||
* @param: blob: the block's blob
|
||||
*
|
||||
* @return true if the block was found in the alternative blocks list, false otherwise
|
||||
*/
|
||||
virtual bool get_alt_block(const crypto::hash &blkid, alt_block_data_t *data, cryptonote::blobdata *blob) = 0;
|
||||
|
||||
/**
|
||||
* @brief remove an alternative block
|
||||
*
|
||||
* @param: blkid the block hash
|
||||
*/
|
||||
virtual void remove_alt_block(const crypto::hash &blkid) = 0;
|
||||
|
||||
/**
|
||||
* @brief get the number of alternative blocks stored
|
||||
*/
|
||||
virtual uint64_t get_alt_block_count() = 0;
|
||||
|
||||
/**
|
||||
* @brief drop all alternative blocks
|
||||
*/
|
||||
virtual void drop_alt_blocks() = 0;
|
||||
|
||||
/**
|
||||
* @brief runs a function over all txpool transactions
|
||||
*
|
||||
@@ -1680,23 +1501,6 @@ public:
|
||||
virtual bool for_all_outputs(std::function<bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)> f) const = 0;
|
||||
virtual bool for_all_outputs(uint64_t amount, const std::function<bool(uint64_t height)> &f) const = 0;
|
||||
|
||||
/**
|
||||
* @brief runs a function over all alternative blocks stored
|
||||
*
|
||||
* The subclass should run the passed function for each alt block it has
|
||||
* stored, passing (blkid, data, blob) as its parameters.
|
||||
*
|
||||
* If any call to the function returns false, the subclass should return
|
||||
* false. Otherwise, the subclass returns true.
|
||||
*
|
||||
* The subclass should throw DB_ERROR if any of the expected values are
|
||||
* not found. Current implementations simply return false.
|
||||
*
|
||||
* @param std::function f the function to run
|
||||
*
|
||||
* @return false if the function returns false for any output, otherwise true
|
||||
*/
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata *blob)> f, bool include_blob = false) const = 0;
|
||||
|
||||
|
||||
//
|
||||
@@ -1780,52 +1584,6 @@ public:
|
||||
|
||||
}; // class BlockchainDB
|
||||
|
||||
class db_txn_guard
|
||||
{
|
||||
public:
|
||||
db_txn_guard(BlockchainDB *db, bool readonly): db(db), readonly(readonly), active(false)
|
||||
{
|
||||
if (readonly)
|
||||
{
|
||||
active = db->block_rtxn_start();
|
||||
}
|
||||
else
|
||||
{
|
||||
db->block_wtxn_start();
|
||||
active = true;
|
||||
}
|
||||
}
|
||||
virtual ~db_txn_guard()
|
||||
{
|
||||
if (active)
|
||||
stop();
|
||||
}
|
||||
void stop()
|
||||
{
|
||||
if (readonly)
|
||||
db->block_rtxn_stop();
|
||||
else
|
||||
db->block_wtxn_stop();
|
||||
active = false;
|
||||
}
|
||||
void abort()
|
||||
{
|
||||
if (readonly)
|
||||
db->block_rtxn_abort();
|
||||
else
|
||||
db->block_wtxn_abort();
|
||||
active = false;
|
||||
}
|
||||
|
||||
private:
|
||||
BlockchainDB *db;
|
||||
bool readonly;
|
||||
bool active;
|
||||
};
|
||||
|
||||
class db_rtxn_guard: public db_txn_guard { public: db_rtxn_guard(BlockchainDB *db): db_txn_guard(db, true) {} };
|
||||
class db_wtxn_guard: public db_txn_guard { public: db_wtxn_guard(BlockchainDB *db): db_txn_guard(db, false) {} };
|
||||
|
||||
BlockchainDB *new_db(const std::string& db_type);
|
||||
|
||||
} // namespace cryptonote
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user