Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61f22fcfd4 | |||
| bf1bf393c8 | |||
| 39e244a11c | |||
| 6724dfc832 | |||
| 9dadba6b09 | |||
| c432817d5f | |||
| 7ceb1f6a4d | |||
| 1a2793bb88 | |||
| 7ee2f00224 | |||
| 383a3b8b02 | |||
| 0beca5d801 | |||
| 47bd5bf083 | |||
| 7b5b80cb3a | |||
| b50eecc56f | |||
| 8953173403 | |||
| 2f307c195c | |||
| 8c5024a78a | |||
| 3f823e8583 | |||
| a4bfc6012a | |||
| 136d446157 | |||
| 1966f49ce2 |
@@ -9,7 +9,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
VERSION: "5.1.9"
|
||||
VERSION: "5.2.0"
|
||||
|
||||
jobs:
|
||||
build-windows-qt:
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
# Embedded Tor Integration Guide for Triangles
|
||||
|
||||
This guide explains how to compile Tor as a static library (`libtor.a`) and link
|
||||
it directly into the Triangles wallet binary so that every node automatically
|
||||
runs a Tor hidden service without needing an external Tor installation.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
trianglesd / triangles-qt
|
||||
├── tor_embedded.cpp ← calls tor_run_main() in a background thread
|
||||
├── tor_process.cpp ← fallback: launches external tor binary (already works)
|
||||
├── onion_v3.cpp ← V3 onion address generation / SOCKS5 proxy logic
|
||||
└── libtor.a ← aggregate static Tor library (built from official source)
|
||||
```
|
||||
|
||||
When compiled with `ENABLE_TOR_EMBEDDED`, the wallet calls `tor_run_main()` from
|
||||
`tor_api.h` on a dedicated thread. This gives the wallet a SOCKS5 proxy on
|
||||
`127.0.0.1:19099` and a V3 hidden service on port 24112 (the P2P port).
|
||||
|
||||
When compiled **without** the flag, `tor_embedded.cpp` falls back to the external
|
||||
`tor_process.cpp` which searches for and launches a system `tor` binary.
|
||||
|
||||
## Step 1: Add Tor as a Git Submodule
|
||||
|
||||
```bash
|
||||
cd /path/to/triangles
|
||||
git submodule add https://gitlab.torproject.org/tpo/core/tor.git src/tor/tor-src
|
||||
cd src/tor/tor-src
|
||||
git checkout release-0.4.9 # latest stable branch as of 2026
|
||||
```
|
||||
|
||||
This puts the full Tor source at `src/tor/tor-src/`.
|
||||
Current imported checkout in this repo: `release-0.4.9` at commit `1442ca4`.
|
||||
There is also a helper build script at `src/tor/build-libtor.sh`.
|
||||
|
||||
## Step 2: Build libtor.a
|
||||
|
||||
Tor uses autotools. Build it as a static library:
|
||||
|
||||
```bash
|
||||
cd src/tor/tor-src
|
||||
|
||||
# Install Tor build dependencies
|
||||
sudo apt install autoconf automake libtool pkg-config \
|
||||
libssl-dev libevent-dev zlib1g-dev
|
||||
|
||||
# Generate configure script
|
||||
./autogen.sh
|
||||
|
||||
# Configure for static library build (disable unneeded modules)
|
||||
./configure \
|
||||
--enable-static-tor \
|
||||
--disable-module-relay \
|
||||
--disable-module-dirauth \
|
||||
--disable-asciidoc \
|
||||
--disable-manpage \
|
||||
--disable-html-manual \
|
||||
--disable-unittests \
|
||||
--disable-tool-name-check \
|
||||
--with-openssl-dir=/usr \
|
||||
--with-libevent-dir=/usr \
|
||||
--with-zlib-dir=/usr \
|
||||
--prefix=/usr/local
|
||||
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
Or from the repo root:
|
||||
```bash
|
||||
./src/tor/build-libtor.sh
|
||||
```
|
||||
|
||||
After building, the static libraries are in `src/tor/tor-src/`:
|
||||
- `libtor.a`
|
||||
- `src/lib/libtor-*.a` (multiple component libs)
|
||||
|
||||
The header `src/feature/api/tor_api.h` provides the public C API:
|
||||
```c
|
||||
tor_main_configuration_t *tor_main_configuration_new(void);
|
||||
int tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
|
||||
int argc, char *argv[]);
|
||||
int tor_run_main(const tor_main_configuration_t *);
|
||||
void tor_main_configuration_free(tor_main_configuration_t *);
|
||||
```
|
||||
|
||||
## Step 3: Build Triangles with Embedded Tor
|
||||
|
||||
### Linux (makefile.unix)
|
||||
|
||||
```bash
|
||||
cd src
|
||||
|
||||
# Point to Tor's built libraries and headers
|
||||
make -f makefile.unix \
|
||||
USE_TOR_EMBEDDED=1
|
||||
```
|
||||
|
||||
You may need to adjust the `-l` flags in the makefile depending on the exact
|
||||
library names Tor produces. Check `src/tor/tor-src/` after building:
|
||||
|
||||
```bash
|
||||
find tor/tor-src -name '*.a' | sort
|
||||
```
|
||||
|
||||
On the imported `release-0.4.9` checkout in this repo, the simplest working
|
||||
link path is the aggregate `libtor.a` plus the normal dependency libraries.
|
||||
|
||||
### Windows (triangles-qt.pro)
|
||||
|
||||
Add to `triangles-qt.pro`:
|
||||
```qmake
|
||||
qmake "USE_TOR_EMBEDDED=1" \
|
||||
"TOR_SOURCE_ROOT=src/tor/tor-src"
|
||||
```
|
||||
|
||||
Both build systems now default to:
|
||||
- source root: `src/tor/tor-src`
|
||||
- include path: `src/tor/tor-src/src/feature/api`
|
||||
- library path: `src/tor/tor-src`
|
||||
- embedded Tor library: `-ltor`
|
||||
|
||||
On Windows, the imported Tor `0.4.9.5` build also needed:
|
||||
- `-llzma`
|
||||
- `-lzstd`
|
||||
- `-liphlpapi`
|
||||
- `-lshlwapi` (already linked by Triangles)
|
||||
|
||||
## Step 4: Wire into init.cpp
|
||||
|
||||
The global hooks `StartEmbeddedTor()` and `StopEmbeddedTor()` need to be called
|
||||
from `init.cpp`. Add these calls:
|
||||
|
||||
### In AppInit2() (after network init, before starting node):
|
||||
```cpp
|
||||
#include "tor/tor_embedded.h"
|
||||
|
||||
// Near the end of AppInit2, after network initialization:
|
||||
if (!StartEmbeddedTor()) {
|
||||
printf("WARNING: Embedded Tor failed to start. .onion connectivity unavailable.\n");
|
||||
// Non-fatal: wallet works without Tor, just no .onion
|
||||
}
|
||||
```
|
||||
|
||||
### In Shutdown():
|
||||
```cpp
|
||||
StopEmbeddedTor();
|
||||
```
|
||||
|
||||
## Step 5: Configure SOCKS Proxy for Outbound Connections
|
||||
|
||||
After Tor starts, the wallet needs to route `.onion` connections through the
|
||||
SOCKS5 proxy. In `net.cpp`, after Tor is initialized:
|
||||
|
||||
```cpp
|
||||
// If embedded Tor is running, use its SOCKS proxy for .onion addresses
|
||||
CTorEmbedded* tor = CTorEmbedded::GetInstance();
|
||||
if (tor->IsRunning()) {
|
||||
// Set proxy for .onion connections
|
||||
proxyType addrProxy(CService("127.0.0.1", tor->GetSocksPort()), 5);
|
||||
SetNameProxy(addrProxy);
|
||||
}
|
||||
```
|
||||
|
||||
## Runtime Flags
|
||||
|
||||
The embedded Tor respects these command-line flags:
|
||||
|
||||
| Flag | Default | Description |
|
||||
|------|---------|-------------|
|
||||
| `-notor` | false | Disable Tor entirely |
|
||||
| `-torsocks=PORT` | 19099 | SOCKS5 proxy port |
|
||||
| `-torhsport=PORT` | 24112 | Hidden service virtual port |
|
||||
|
||||
## File Layout After Integration
|
||||
|
||||
```
|
||||
src/tor/
|
||||
├── tor-src/ ← git submodule (official Tor repo)
|
||||
│ └── src/
|
||||
│ ├── lib/libtor-*.a
|
||||
│ └── feature/api/tor_api.h
|
||||
│ └── libtor.a
|
||||
├── tor_embedded.h ← CTorEmbedded class header
|
||||
├── tor_embedded.cpp ← implementation (calls tor_run_main)
|
||||
├── tor_process.h ← external Tor process manager (fallback)
|
||||
├── tor_process.cpp
|
||||
├── onion_v3.h ← V3 onion address utilities
|
||||
├── onion_v3.cpp
|
||||
├── anonymize.h ← data dir helpers
|
||||
├── anonymize.cpp
|
||||
└── LICENSE
|
||||
```
|
||||
|
||||
## Reference: How VERGE (XVG) Does It
|
||||
|
||||
VERGE uses the same pattern. Their implementation is at:
|
||||
- `src/torcontroller.cpp` (~100 lines)
|
||||
- They use `tor_main()` (older API, pre-0.4.5)
|
||||
- Git submodule at `src/tor/` pointing to `release-0.4.8` branch
|
||||
- Build Tor as part of their `depends/` system
|
||||
|
||||
Key difference: modern Tor (0.4.5+) uses `tor_run_main()` with a configuration
|
||||
object instead of raw `tor_main(int argc, char** argv)`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Tor fails to bootstrap**: Check firewall rules. Tor needs outbound TCP to the
|
||||
Tor network (ports 80, 443, 9001, 9030).
|
||||
|
||||
**Link errors with libtor**: Prefer the aggregate `libtor.a` from the top level
|
||||
of the Tor build tree. On the imported Windows/MSYS2 build in this repo, the
|
||||
minimal verified link set was:
|
||||
```
|
||||
-ltor -levent -lssl -lcrypto -lz -llzma -lzstd -lws2_32 -liphlpapi -lshlwapi
|
||||
```
|
||||
|
||||
**OpenSSL version mismatch**: Both Tor and Triangles must link against the same
|
||||
OpenSSL version (3.x). If Tor was built against a different OpenSSL, rebuild it
|
||||
with the same `--with-openssl-dir`.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Embedded Tor Rebase Notes
|
||||
|
||||
This repository currently contains a legacy Tor source snapshot under
|
||||
`src/tor/`, but the wallet target does not build most of that tree.
|
||||
|
||||
## Current state
|
||||
|
||||
- The vendored Tor headers report `0.2.5.1-alpha-dev` in:
|
||||
- `src/tor/orconfig_linux.h`
|
||||
- `src/tor/orconfig_apple.h`
|
||||
- `src/tor/orconfig_win32.h`
|
||||
- The Qt wallet target currently builds only these Tor-related sources:
|
||||
- `src/tor_embed_hooks.cpp`
|
||||
- `src/tor/onion_v3.cpp`
|
||||
- `src/tor/tor_process.cpp`
|
||||
- This means the large legacy `src/tor/` tree is mostly dormant from the
|
||||
wallet build's perspective.
|
||||
|
||||
## Rebase target
|
||||
|
||||
- Target upstream Tor line: `0.4.9.x`
|
||||
- Imported source tree: `src/tor/tor-src`
|
||||
- Imported branch: `release-0.4.9`
|
||||
- Imported commit: `1442ca4`
|
||||
|
||||
## Why this matters
|
||||
|
||||
Attempting to "upgrade embedded Tor" by rebasing the entire old source tree in
|
||||
place is unnecessarily expensive if the wallet is only relying on:
|
||||
|
||||
- process management for a bundled Tor executable
|
||||
- Tor v3 onion address/key handling
|
||||
- a few local embedding hooks
|
||||
|
||||
The migration should preserve the embedded product experience while reducing
|
||||
coupling to legacy upstream Tor internals.
|
||||
|
||||
## Strategy
|
||||
|
||||
1. Keep the product-level embedding model.
|
||||
- The wallet can still ship with Tor and launch it automatically.
|
||||
2. Separate Triangles-owned glue from vendored Tor code.
|
||||
- `src/tor_embed_hooks.*` now holds local process/bootstrap helpers that
|
||||
previously lived under `src/tor/anonymize.*`.
|
||||
3. Treat `src/tor/onion_v3.cpp` and `src/tor/tor_process.cpp` as the active
|
||||
compatibility boundary.
|
||||
4. Re-vendor a newer upstream Tor snapshot only after deciding whether the
|
||||
product truly needs upstream Tor source in-tree or only a bundled Tor
|
||||
runtime plus the wallet's own v3/onion management code.
|
||||
|
||||
## Immediate next tasks
|
||||
|
||||
1. Audit whether any live build target still includes legacy `src/tor/*.c`
|
||||
sources beyond the current wallet target.
|
||||
2. Decide whether `onion_v3.cpp` should remain wallet-owned code or be reduced
|
||||
further in favor of runtime Tor control/provisioning.
|
||||
3. Add build metadata recording the intended upstream Tor version and source.
|
||||
4. If full upstream vendoring is still required, import a fresh `0.4.8.19`
|
||||
tree side-by-side instead of trying to patch the legacy `0.2.5.1` tree.
|
||||
+3
-4
@@ -5,7 +5,6 @@
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <map>
|
||||
|
||||
#include "alert.h"
|
||||
@@ -46,10 +45,10 @@ void CUnsignedAlert::SetNull()
|
||||
std::string CUnsignedAlert::ToString() const
|
||||
{
|
||||
std::string strSetCancel;
|
||||
BOOST_FOREACH(int n, setCancel)
|
||||
for (int n : setCancel)
|
||||
strSetCancel += strprintf("%d ", n);
|
||||
std::string strSetSubVer;
|
||||
BOOST_FOREACH(std::string str, setSubVer)
|
||||
for (std::string str : setSubVer)
|
||||
strSetSubVer += "\"" + str + "\" ";
|
||||
return strprintf(
|
||||
"CAlert(\n"
|
||||
@@ -228,7 +227,7 @@ bool CAlert::ProcessAlert(bool fThread)
|
||||
}
|
||||
|
||||
// Check if this alert has been cancelled
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||
for (auto& item : mapAlerts)
|
||||
{
|
||||
const CAlert& alert = item.second;
|
||||
if (alert.Cancels(*this))
|
||||
|
||||
+2
-2
@@ -260,7 +260,7 @@ public:
|
||||
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
||||
*/
|
||||
class CTrianglesAddress;
|
||||
class CTrianglesAddressVisitor : public boost::static_visitor<bool>
|
||||
class CTrianglesAddressVisitor
|
||||
{
|
||||
private:
|
||||
CTrianglesAddress *addr;
|
||||
@@ -294,7 +294,7 @@ public:
|
||||
|
||||
bool Set(const CTxDestination &dest)
|
||||
{
|
||||
return boost::apply_visitor(CTrianglesAddressVisitor(this), dest);
|
||||
return std::visit(CTrianglesAddressVisitor(this), dest);
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
|
||||
+42
-67
@@ -2,9 +2,6 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "checkpoints.h"
|
||||
|
||||
#include "txdb.h"
|
||||
@@ -22,39 +19,37 @@ namespace Checkpoints
|
||||
// timestamp before)
|
||||
// + Contains no strange transactions
|
||||
//
|
||||
static MapCheckpoints mapCheckpoints =
|
||||
boost::assign::map_list_of
|
||||
( 0, hashGenesisBlockOfficial )
|
||||
( 2000, uint256("0x0000000000b5f20078bf46ebdf1500813bb6b2cb482065aa93b89e073b2c6467"))
|
||||
( 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059"))
|
||||
( 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e"))
|
||||
( 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51"))
|
||||
( 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6"))
|
||||
( 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b"))
|
||||
( 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db"))
|
||||
( 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007"))
|
||||
( 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249"))
|
||||
( 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6"))
|
||||
( 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47"))
|
||||
(2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0"))
|
||||
;
|
||||
static MapCheckpoints mapCheckpoints = {
|
||||
{ 0, hashGenesisBlockOfficial },
|
||||
{ 2000, uint256("0x0000000000b5f20078bf46ebdf1500813bb6b2cb482065aa93b89e073b2c6467")},
|
||||
{ 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059")},
|
||||
{ 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e")},
|
||||
{ 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b")},
|
||||
{ 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db")},
|
||||
{ 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007")},
|
||||
{ 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249")},
|
||||
{ 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6")},
|
||||
{ 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47")},
|
||||
{2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0")},
|
||||
};
|
||||
|
||||
static MapCheckpoints mapCheckpointsTestnet =
|
||||
boost::assign::map_list_of
|
||||
( 0, hashGenesisBlockTestNet )
|
||||
( 2000, uint256("0x0000000000b5f20078bf46ebdf1500813bb6b2cb482065aa93b89e073b2c6467"))
|
||||
( 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059"))
|
||||
( 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e"))
|
||||
( 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51"))
|
||||
( 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6"))
|
||||
( 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b"))
|
||||
( 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db"))
|
||||
( 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007"))
|
||||
( 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249"))
|
||||
( 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6"))
|
||||
( 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47"))
|
||||
(2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0"))
|
||||
;
|
||||
static MapCheckpoints mapCheckpointsTestnet = {
|
||||
{ 0, hashGenesisBlockTestNet },
|
||||
{ 2000, uint256("0x0000000000b5f20078bf46ebdf1500813bb6b2cb482065aa93b89e073b2c6467")},
|
||||
{ 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059")},
|
||||
{ 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e")},
|
||||
{ 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b")},
|
||||
{ 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db")},
|
||||
{ 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007")},
|
||||
{ 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249")},
|
||||
{ 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6")},
|
||||
{ 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47")},
|
||||
{2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0")},
|
||||
};
|
||||
|
||||
bool CheckHardened(int nHeight, const uint256& hash)
|
||||
{
|
||||
@@ -76,9 +71,9 @@ namespace Checkpoints
|
||||
{
|
||||
MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);
|
||||
|
||||
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
|
||||
for (auto it = checkpoints.rbegin(); it != checkpoints.rend(); ++it)
|
||||
{
|
||||
const uint256& hash = i.second;
|
||||
const uint256& hash = it->second;
|
||||
std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
|
||||
if (t != mapBlockIndex.end())
|
||||
return t->second;
|
||||
@@ -87,8 +82,8 @@ namespace Checkpoints
|
||||
}
|
||||
|
||||
// triangles: synchronized checkpoint (centrally broadcasted)
|
||||
uint256 hashSyncCheckpoint = uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0");
|
||||
uint256 hashPendingCheckpoint = uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0");
|
||||
uint256 hashSyncCheckpoint = uint256("0x7e7a6e4dd5fe895106fca912dfbacaeaf2a89e76c6a588df8ff96e0e18b96021");
|
||||
uint256 hashPendingCheckpoint = uint256("0x7e7a6e4dd5fe895106fca912dfbacaeaf2a89e76c6a588df8ff96e0e18b96021");
|
||||
CSyncCheckpoint checkpointMessage;
|
||||
CSyncCheckpoint checkpointMessagePending;
|
||||
uint256 hashInvalidCheckpoint = 0;
|
||||
@@ -199,7 +194,7 @@ namespace Checkpoints
|
||||
// relay the checkpoint
|
||||
if (!checkpointMessage.IsNull())
|
||||
{
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
checkpointMessage.RelayTo(pnode);
|
||||
}
|
||||
return true;
|
||||
@@ -218,30 +213,10 @@ namespace Checkpoints
|
||||
}
|
||||
|
||||
// Check against synchronized checkpoint
|
||||
// Disabled: master key removed in V5, no new sync checkpoints possible.
|
||||
// Always returns true to prevent stale DB-persisted checkpoints from blocking IBD.
|
||||
bool CheckSync(const uint256& hashBlock, const CBlockIndex* pindexPrev)
|
||||
{
|
||||
if (fTestNet) return true; // Testnet has no checkpoints
|
||||
int nHeight = pindexPrev->nHeight + 1;
|
||||
|
||||
LOCK(cs_hashSyncCheckpoint);
|
||||
// sync-checkpoint should always be accepted block
|
||||
assert(mapBlockIndex.count(hashSyncCheckpoint));
|
||||
const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint];
|
||||
|
||||
if (nHeight > pindexSync->nHeight)
|
||||
{
|
||||
// trace back to same height as sync-checkpoint
|
||||
const CBlockIndex* pindex = pindexPrev;
|
||||
while (pindex->nHeight > pindexSync->nHeight)
|
||||
if (!(pindex = pindex->pprev))
|
||||
return error("CheckSync: pprev null - block index structure failure");
|
||||
if (pindex->nHeight < pindexSync->nHeight || pindex->GetBlockHash() != hashSyncCheckpoint)
|
||||
return false; // only descendant of sync-checkpoint can pass check
|
||||
}
|
||||
if (nHeight == pindexSync->nHeight && hashBlock != hashSyncCheckpoint)
|
||||
return false; // same height with sync-checkpoint
|
||||
if (nHeight < pindexSync->nHeight && !mapBlockIndex.count(hashBlock))
|
||||
return false; // lower height than sync-checkpoint
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -284,9 +259,9 @@ namespace Checkpoints
|
||||
printf("ResetSyncCheckpoint: pending for sync-checkpoint %s\n", hashPendingCheckpoint.ToString().c_str());
|
||||
}
|
||||
|
||||
BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
|
||||
for (auto it = mapCheckpoints.rbegin(); it != mapCheckpoints.rend(); ++it)
|
||||
{
|
||||
const uint256& hash = i.second;
|
||||
const uint256& hash = it->second;
|
||||
if (mapBlockIndex.count(hash) && mapBlockIndex[hash]->IsInMainChain())
|
||||
{
|
||||
if (!WriteSyncCheckpoint(hash))
|
||||
@@ -351,7 +326,7 @@ namespace Checkpoints
|
||||
// Relay checkpoint
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
checkpoint.RelayTo(pnode);
|
||||
}
|
||||
return true;
|
||||
@@ -361,8 +336,8 @@ namespace Checkpoints
|
||||
bool IsMatureSyncCheckpoint()
|
||||
{
|
||||
LOCK(cs_hashSyncCheckpoint);
|
||||
// sync-checkpoint should always be accepted block
|
||||
assert(mapBlockIndex.count(hashSyncCheckpoint));
|
||||
if (!mapBlockIndex.count(hashSyncCheckpoint))
|
||||
return true; // no valid sync checkpoint, treat as mature
|
||||
const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint];
|
||||
return (nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity ||
|
||||
pindexSync->GetBlockTime() + nStakeMinAge < GetAdjustedTime());
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
|
||||
// These need to be macros, as version.cpp's and triangles-qt.rc's voodoo requires it
|
||||
#define CLIENT_VERSION_MAJOR 5
|
||||
#define CLIENT_VERSION_MINOR 1
|
||||
#define CLIENT_VERSION_REVISION 9
|
||||
#define CLIENT_VERSION_MINOR 3
|
||||
#define CLIENT_VERSION_REVISION 2
|
||||
#define CLIENT_VERSION_BUILD 0
|
||||
|
||||
// Converts the parameter X to a string after macro replacement on X has been performed.
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ bool CDBEnv::Open(fs::path pathEnv_)
|
||||
if (GetBoolArg("-privdb", true))
|
||||
nEnvFlags |= DB_PRIVATE;
|
||||
|
||||
int nDbCache = GetArg("-dbcache", 128);
|
||||
int nDbCache = GetArg("-dbcache", 2048);
|
||||
dbenv.set_lg_dir(pathLogDir.string().c_str());
|
||||
dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1);
|
||||
dbenv.set_lg_bsize(1048576);
|
||||
|
||||
+17
-11
@@ -11,6 +11,8 @@
|
||||
#include "ui_interface.h"
|
||||
#include "checkpoints.h"
|
||||
#include "smessage.h"
|
||||
#include "openssl_compat.h"
|
||||
#include "tor/tor_embedded.h"
|
||||
#include "tor/onion_v3.h"
|
||||
#include "tor/tor_process.h"
|
||||
#ifdef ENABLE_ZMQ
|
||||
@@ -156,7 +158,7 @@ void Shutdown(void* parg)
|
||||
|
||||
SecureMsgShutdown();
|
||||
ShutdownTorV3();
|
||||
StopTorProcess();
|
||||
StopEmbeddedTor();
|
||||
|
||||
#ifdef ENABLE_ZMQ
|
||||
if (pzmqNotifier)
|
||||
@@ -332,6 +334,9 @@ std::string HelpMessage()
|
||||
//" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
|
||||
//" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
|
||||
" -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n"
|
||||
" -notor " + _("Disable Tor startup and .onion connectivity") + "\n" +
|
||||
" -torsocks=<port> " + _("Set embedded or managed Tor SOCKS proxy port (default: 19099)") + "\n" +
|
||||
" -torhsport=<port> " + _("Set embedded or managed Tor hidden service port (default: wallet listen port)") + "\n" +
|
||||
//" -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
|
||||
" -port=<port> " + _("Listen for connections on <port> (default: 24112 or testnet: 24111)") + "\n" +
|
||||
" -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
|
||||
@@ -651,7 +656,7 @@ bool AppInit2()
|
||||
ShrinkDebugFile();
|
||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
printf("Triangles version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
|
||||
printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
|
||||
printf("Using OpenSSL version %s\n", TrianglesOpenSSLVersionString());
|
||||
if (!fLogTimestamps)
|
||||
printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
||||
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
|
||||
@@ -709,7 +714,7 @@ bool AppInit2()
|
||||
// Users can restrict to Tor-only with -onlynet=tor
|
||||
if (mapArgs.count("-onlynet")) {
|
||||
std::set<enum Network> nets;
|
||||
BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
|
||||
for (std::string snet : mapMultiArgs["-onlynet"]) {
|
||||
enum Network net = ParseNetwork(snet);
|
||||
if (net == NET_UNROUTABLE)
|
||||
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
|
||||
@@ -761,11 +766,11 @@ bool AppInit2()
|
||||
|
||||
|
||||
// Release the old Tor initialization mutex (no longer blocking on embedded Tor)
|
||||
set_initialized();
|
||||
triangles_tor_set_initialized();
|
||||
|
||||
if (mapArgs.count("-externalip"))
|
||||
{
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
|
||||
for (string strAddr : mapMultiArgs["-externalip"]) {
|
||||
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
|
||||
if (!addrLocal.IsValid())
|
||||
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
|
||||
@@ -789,7 +794,7 @@ bool AppInit2()
|
||||
InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n"));
|
||||
}
|
||||
|
||||
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
|
||||
for (string strDest : mapMultiArgs["-seednode"])
|
||||
AddOneShot(strDest);
|
||||
|
||||
// ********************************************************* Step 7: load blockchain
|
||||
@@ -971,13 +976,14 @@ bool AppInit2()
|
||||
uiInterface.InitMessage(_("Starting Tor..."));
|
||||
printf("Starting Tor process...\n");
|
||||
|
||||
// Start the Tor process (finds/launches tor binary, provides SOCKS proxy)
|
||||
std::string torDataPath = (GetDataDir() / "tor_data").string();
|
||||
bool torStarted = StartTorProcess(torDataPath);
|
||||
bool torStarted = StartEmbeddedTor();
|
||||
std::string torDataPath = CTorEmbedded::GetInstance()->GetDataDir();
|
||||
if (torDataPath.empty())
|
||||
torDataPath = (GetDataDir() / "tor_data").string();
|
||||
|
||||
if (torStarted) {
|
||||
printf("Tor process running, SOCKS proxy at %s\n",
|
||||
CTorProcess::GetInstance()->GetSocksProxy().c_str());
|
||||
CTorEmbedded::GetInstance()->GetSocksProxy().c_str());
|
||||
} else {
|
||||
printf("WARNING: Tor not available. .onion peers will not be reachable.\n");
|
||||
printf(" Clearnet connections will still work normally.\n");
|
||||
@@ -1041,7 +1047,7 @@ bool AppInit2()
|
||||
{
|
||||
uiInterface.InitMessage(_("Importing blockchain data file."));
|
||||
|
||||
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
|
||||
for (string strFile : mapMultiArgs["-loadblock"])
|
||||
{
|
||||
FILE *file = fopen(strFile.c_str(), "rb");
|
||||
if (file)
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#define TRIANGLES_INIT_H
|
||||
|
||||
#include "wallet.h"
|
||||
#include <tor/anonymize.h>
|
||||
#include "tor_embed_hooks.h"
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
extern std::string strWalletFileName;
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#include <stdexcept>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
|
||||
+5
-8
@@ -2,8 +2,6 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include "kernel.h"
|
||||
#include "txdb.h"
|
||||
|
||||
@@ -19,10 +17,9 @@ extern unsigned int nTargetSpacing;
|
||||
typedef std::map<int, unsigned int> MapModifierCheckpoints;
|
||||
|
||||
// Hard checkpoints of stake modifiers to ensure they are deterministic
|
||||
static std::map<int, unsigned int> mapStakeModifierCheckpoints =
|
||||
boost::assign::map_list_of
|
||||
( 0, 0x000000000e00670b )
|
||||
;
|
||||
static std::map<int, unsigned int> mapStakeModifierCheckpoints = {
|
||||
{ 0, 0x000000000e00670b },
|
||||
};
|
||||
|
||||
// Get time weight
|
||||
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd)
|
||||
@@ -80,7 +77,7 @@ static bool SelectBlockFromCandidates(vector<pair<int64_t, uint256> >& vSortedBy
|
||||
bool fSelected = false;
|
||||
uint256 hashBest = 0;
|
||||
*pindexSelected = (const CBlockIndex*) 0;
|
||||
BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)& item, vSortedByTimestamp)
|
||||
for (const auto& item : vSortedByTimestamp)
|
||||
{
|
||||
if (!mapBlockIndex.count(item.second))
|
||||
return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str());
|
||||
@@ -199,7 +196,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod
|
||||
strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
BOOST_FOREACH(const PAIRTYPE(uint256, const CBlockIndex*)& item, mapSelectedBlocks)
|
||||
for (const auto& item : mapSelectedBlocks)
|
||||
{
|
||||
// 'S' indicates selected proof-of-stake blocks
|
||||
// 'W' indicates selected proof-of-work blocks
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||
return false;
|
||||
|
||||
fUseCrypto = true;
|
||||
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
|
||||
for (KeyMap::value_type& mKey : mapKeys)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetSecret(mKey.second.first, mKey.second.second))
|
||||
|
||||
+10
-22
@@ -1,24 +1,12 @@
|
||||
LZ4 Library
|
||||
Copyright (c) 2011-2014, Yann Collet
|
||||
All rights reserved.
|
||||
This repository uses 2 different licenses :
|
||||
- all files in the `lib` directory use a BSD 2-Clause license
|
||||
- all other files use a GPL-2.0-or-later license, unless explicitly stated otherwise
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
Relevant license is reminded at the top of each source file,
|
||||
and with presence of COPYING or LICENSE file in associated directories.
|
||||
|
||||
* 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.
|
||||
|
||||
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.
|
||||
This model is selected to emphasize that
|
||||
files in the `lib` directory are designed to be included into 3rd party applications,
|
||||
while all other files, in `programs`, `tests` or `examples`,
|
||||
are intended to be used "as is", as part of their intended scenarios,
|
||||
with no intention to support 3rd party integration use cases.
|
||||
|
||||
+2571
-622
File diff suppressed because it is too large
Load Diff
+808
-172
File diff suppressed because it is too large
Load Diff
+182
-130
@@ -120,7 +120,7 @@ void UnregisterWallet(CWallet* pwalletIn)
|
||||
// check whether the passed transaction is from us
|
||||
bool static IsFromMe(CTransaction& tx)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
if (pwallet->IsFromMe(tx))
|
||||
return true;
|
||||
return false;
|
||||
@@ -129,7 +129,7 @@ bool static IsFromMe(CTransaction& tx)
|
||||
// get the wallet transaction with the given hash (if it exists)
|
||||
bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
if (pwallet->GetTransaction(hashTx,wtx))
|
||||
return true;
|
||||
return false;
|
||||
@@ -138,7 +138,7 @@ bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
|
||||
// erases transaction with the given hash from all wallets
|
||||
void static EraseFromWallets(uint256 hash)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->EraseFromWallet(hash);
|
||||
}
|
||||
|
||||
@@ -150,21 +150,21 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate,
|
||||
// triangles: wallets need to refund inputs when disconnecting coinstake
|
||||
if (tx.IsCoinStake())
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
if (pwallet->IsFromMe(tx))
|
||||
pwallet->DisableTransaction(tx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
|
||||
}
|
||||
|
||||
// notify wallets about a new best chain
|
||||
void static SetBestChain(const CBlockLocator& loc)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->SetBestChain(loc);
|
||||
}
|
||||
|
||||
@@ -186,28 +186,28 @@ static bool UpdateAddressIndexSyncState(CTxDB& txdb, const CBlockIndex* pindexNe
|
||||
// notify wallets about an updated transaction
|
||||
void static UpdatedTransaction(const uint256& hashTx)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->UpdatedTransaction(hashTx);
|
||||
}
|
||||
|
||||
// dump all wallets
|
||||
void static PrintWallets(const CBlock& block)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->PrintWallet(block);
|
||||
}
|
||||
|
||||
// notify wallets about an incoming inventory (for request counts)
|
||||
void static Inventory(const uint256& hash)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->Inventory(hash);
|
||||
}
|
||||
|
||||
// ask wallets to resend their transactions
|
||||
void ResendWalletTransactions(bool fForce)
|
||||
{
|
||||
BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
|
||||
for (CWallet* pwallet : setpwalletRegistered)
|
||||
pwallet->ResendWalletTransactions(fForce);
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ bool AddOrphanTx(const CTransaction& tx)
|
||||
}
|
||||
|
||||
mapOrphanTransactions[hash] = tx;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
|
||||
|
||||
printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().substr(0,10).c_str(),
|
||||
@@ -258,7 +258,7 @@ void static EraseOrphanTx(uint256 hash)
|
||||
if (!mapOrphanTransactions.count(hash))
|
||||
return;
|
||||
const CTransaction& tx = mapOrphanTransactions[hash];
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash);
|
||||
if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty())
|
||||
@@ -327,7 +327,7 @@ bool CTransaction::IsStandard() const
|
||||
if (nVersion > CTransaction::CURRENT_VERSION)
|
||||
return false;
|
||||
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
{
|
||||
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG
|
||||
// pay-to-script-hash, which is 3 ~80-byte signatures, 3
|
||||
@@ -340,7 +340,7 @@ bool CTransaction::IsStandard() const
|
||||
return false;
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const CTxOut& txout, vout) {
|
||||
for (const CTxOut& txout : vout) {
|
||||
if (!::IsStandard(txout.scriptPubKey))
|
||||
return false;
|
||||
if (txout.nValue == 0)
|
||||
@@ -421,11 +421,11 @@ unsigned int
|
||||
CTransaction::GetLegacySigOpCount() const
|
||||
{
|
||||
unsigned int nSigOps = 0;
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
{
|
||||
nSigOps += txin.scriptSig.GetSigOpCount(false);
|
||||
}
|
||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
||||
for (const CTxOut& txout : vout)
|
||||
{
|
||||
nSigOps += txout.scriptPubKey.GetSigOpCount(false);
|
||||
}
|
||||
@@ -519,7 +519,7 @@ bool CTransaction::CheckTransaction() const
|
||||
|
||||
// Check for duplicate inputs
|
||||
set<COutPoint> vInOutPoints;
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
{
|
||||
if (vInOutPoints.count(txin.prevout))
|
||||
return false;
|
||||
@@ -533,7 +533,7 @@ bool CTransaction::CheckTransaction() const
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
if (txin.prevout.IsNull())
|
||||
return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
|
||||
}
|
||||
@@ -552,7 +552,7 @@ int64_t CTransaction::GetMinFee(unsigned int nBlockSize, enum GetMinFee_mode mod
|
||||
// To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
|
||||
if (nMinFee < nBaseFee)
|
||||
{
|
||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
||||
for (const CTxOut& txout : vout)
|
||||
if (txout.nValue < CENT)
|
||||
nMinFee = nBaseFee;
|
||||
}
|
||||
@@ -767,7 +767,7 @@ bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive)
|
||||
remove(*it->second.ptx, true);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
mapNextTx.erase(txin.prevout);
|
||||
mapTx.erase(hash);
|
||||
nTransactionsUpdated++;
|
||||
@@ -780,7 +780,7 @@ bool CTxMemPool::removeConflicts(const CTransaction &tx)
|
||||
{
|
||||
// Remove transactions which depend on inputs of tx, recursively
|
||||
LOCK(cs);
|
||||
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
|
||||
for (const CTxIn &txin : tx.vin) {
|
||||
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
|
||||
if (it != mapNextTx.end()) {
|
||||
const CTransaction &txConflict = *it->second.ptx;
|
||||
@@ -882,7 +882,7 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
// Add previous supporting transactions first
|
||||
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
||||
for (CMerkleTx& tx : vtxPrev)
|
||||
{
|
||||
if (!(tx.IsCoinBase() || tx.IsCoinStake()))
|
||||
{
|
||||
@@ -1220,7 +1220,7 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb)
|
||||
// Relinquish previous transactions' spent pointers
|
||||
if (!IsCoinBase())
|
||||
{
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
{
|
||||
COutPoint prevout = txin.prevout;
|
||||
|
||||
@@ -1526,14 +1526,14 @@ static bool GetAddressFromScript(const CScript& script, int& nType, uint160& has
|
||||
if (!ExtractDestination(script, dest))
|
||||
return false;
|
||||
|
||||
const CKeyID* keyId = boost::get<CKeyID>(&dest);
|
||||
const CKeyID* keyId = std::get_if<CKeyID>(&dest);
|
||||
if (keyId) {
|
||||
nType = ADDR_TYPE_P2PKH;
|
||||
hashBytes = *keyId;
|
||||
return true;
|
||||
}
|
||||
|
||||
const CScriptID* scriptId = boost::get<CScriptID>(&dest);
|
||||
const CScriptID* scriptId = std::get_if<CScriptID>(&dest);
|
||||
if (scriptId) {
|
||||
nType = ADDR_TYPE_P2SH;
|
||||
hashBytes = *scriptId;
|
||||
@@ -1627,7 +1627,7 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
|
||||
}
|
||||
|
||||
// triangles: clean up wallet after disconnecting coinstake
|
||||
BOOST_FOREACH(CTransaction& tx, vtx)
|
||||
for (CTransaction& tx : vtx)
|
||||
SyncWithWallets(tx, this, false, false);
|
||||
|
||||
return true;
|
||||
@@ -1660,7 +1660,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
|
||||
int64_t nValueOut = 0;
|
||||
int64_t nStakeReward = 0;
|
||||
unsigned int nSigOps = 0;
|
||||
BOOST_FOREACH(CTransaction& tx, vtx)
|
||||
for (CTransaction& tx : vtx)
|
||||
{
|
||||
uint256 hashTx = tx.GetHash();
|
||||
|
||||
@@ -1692,7 +1692,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
|
||||
// initial block download.
|
||||
CTxIndex txindexOld;
|
||||
if (txdb.ReadTxIndex(hashTx, txindexOld)) {
|
||||
BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)
|
||||
for (CDiskTxPos &pos : txindexOld.vSpent)
|
||||
if (pos.IsNull())
|
||||
return false;
|
||||
}
|
||||
@@ -1852,7 +1852,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
|
||||
// This eliminates millions of per-transaction wallet lookups during sync.
|
||||
if (!fIsInitialDownload)
|
||||
{
|
||||
BOOST_FOREACH(CTransaction& tx, vtx)
|
||||
for (CTransaction& tx : vtx)
|
||||
SyncWithWallets(tx, this, true);
|
||||
}
|
||||
|
||||
@@ -1893,7 +1893,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
|
||||
// Disconnect shorter branch
|
||||
vector<CTransaction> vResurrect;
|
||||
BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
|
||||
for (CBlockIndex* pindex : vDisconnect)
|
||||
{
|
||||
CBlock block;
|
||||
if (!block.ReadFromDisk(pindex))
|
||||
@@ -1902,7 +1902,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str());
|
||||
|
||||
// Queue memory transactions to resurrect
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx)
|
||||
for (const CTransaction& tx : block.vtx)
|
||||
if (!(tx.IsCoinBase() || tx.IsCoinStake()))
|
||||
vResurrect.push_back(tx);
|
||||
}
|
||||
@@ -1922,7 +1922,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
}
|
||||
|
||||
// Queue memory transactions to delete
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx)
|
||||
for (const CTransaction& tx : block.vtx)
|
||||
vDelete.push_back(tx);
|
||||
}
|
||||
if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
|
||||
@@ -1935,21 +1935,21 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
return error("Reorganize() : TxnCommit failed");
|
||||
|
||||
// Disconnect shorter branch
|
||||
BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
|
||||
for (CBlockIndex* pindex : vDisconnect)
|
||||
if (pindex->pprev)
|
||||
pindex->pprev->pnext = NULL;
|
||||
|
||||
// Connect longer branch
|
||||
BOOST_FOREACH(CBlockIndex* pindex, vConnect)
|
||||
for (CBlockIndex* pindex : vConnect)
|
||||
if (pindex->pprev)
|
||||
pindex->pprev->pnext = pindex;
|
||||
|
||||
// Resurrect memory transactions that were in the disconnected branch
|
||||
BOOST_FOREACH(CTransaction& tx, vResurrect)
|
||||
for (CTransaction& tx : vResurrect)
|
||||
tx.AcceptToMemoryPool(txdb, false);
|
||||
|
||||
// Delete redundant memory transactions that are in the connected branch
|
||||
BOOST_FOREACH(CTransaction& tx, vDelete) {
|
||||
for (CTransaction& tx : vDelete) {
|
||||
mempool.remove(tx);
|
||||
mempool.removeConflicts(tx);
|
||||
}
|
||||
@@ -1979,7 +1979,7 @@ bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew)
|
||||
pindexNew->pprev->pnext = pindexNew;
|
||||
|
||||
// Delete redundant memory transactions
|
||||
BOOST_FOREACH(CTransaction& tx, vtx)
|
||||
for (CTransaction& tx : vtx)
|
||||
mempool.remove(tx);
|
||||
|
||||
return true;
|
||||
@@ -2034,8 +2034,9 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
|
||||
}
|
||||
|
||||
// Connect further blocks
|
||||
BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary)
|
||||
for (auto rit = vpindexSecondary.rbegin(); rit != vpindexSecondary.rend(); ++rit)
|
||||
{
|
||||
CBlockIndex *pindex = *rit;
|
||||
CBlock block;
|
||||
if (!block.ReadFromDisk(pindex))
|
||||
{
|
||||
@@ -2176,7 +2177,7 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const
|
||||
if (IsCoinBase())
|
||||
return true;
|
||||
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
{
|
||||
// First try finding the previous transaction in database
|
||||
CTransaction txPrev;
|
||||
@@ -2213,7 +2214,7 @@ bool CBlock::GetCoinAge(uint64_t& nCoinAge) const
|
||||
nCoinAge = 0;
|
||||
|
||||
CTxDB txdb("r");
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
{
|
||||
uint64_t nTxCoinAge;
|
||||
if (tx.GetCoinAge(txdb, nTxCoinAge))
|
||||
@@ -2369,7 +2370,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c
|
||||
}
|
||||
|
||||
// Check transactions
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
{
|
||||
if (!tx.CheckTransaction())
|
||||
return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
|
||||
@@ -2382,7 +2383,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c
|
||||
// Check for duplicate txids. This is caught by ConnectInputs(),
|
||||
// but catching it earlier avoids a potential DoS attack:
|
||||
set<uint256> uniqueTx;
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
{
|
||||
uniqueTx.insert(tx.GetHash());
|
||||
}
|
||||
@@ -2390,7 +2391,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c
|
||||
return DoS(100, error("CheckBlock() : duplicate transaction"));
|
||||
|
||||
unsigned int nSigOps = 0;
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
{
|
||||
nSigOps += tx.GetLegacySigOpCount();
|
||||
}
|
||||
@@ -2447,7 +2448,7 @@ bool CBlock::AcceptBlock()
|
||||
return error("AcceptBlock() : block's timestamp is too early");
|
||||
|
||||
// Check that all transactions are finalized
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
if (!tx.IsFinal(nHeight, GetBlockTime()))
|
||||
return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
|
||||
|
||||
@@ -2471,18 +2472,10 @@ bool CBlock::AcceptBlock()
|
||||
}
|
||||
}
|
||||
|
||||
// Before fork: enforce sync checkpoints for historical chain integrity
|
||||
// After fork: no sync checkpoint enforcement (decentralized)
|
||||
if (nHeight < FORK_HEIGHT_V5)
|
||||
{
|
||||
bool cpSatisfies = Checkpoints::CheckSync(hash, pindexPrev);
|
||||
|
||||
if (CheckpointsMode == Checkpoints::STRICT && !cpSatisfies)
|
||||
return error("AcceptBlock() : rejected by synchronized checkpoint");
|
||||
|
||||
if (CheckpointsMode == Checkpoints::ADVISORY && !cpSatisfies)
|
||||
strMiscWarning = _("WARNING: syncronized checkpoint violation detected, but skipped!");
|
||||
}
|
||||
// Sync checkpoint enforcement is disabled:
|
||||
// - Master key was removed in V5 fork, no new sync checkpoints will be broadcast
|
||||
// - Hardcoded checkpoints already guarantee chain integrity
|
||||
// - The persisted hashSyncCheckpoint in LevelDB blocks IBD from progressing
|
||||
|
||||
// Enforce rule that the coinbase starts with serialized block height
|
||||
CScript expect = CScript() << nHeight;
|
||||
@@ -2505,7 +2498,7 @@ bool CBlock::AcceptBlock()
|
||||
if (hashBestChain == hash)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
|
||||
pnode->PushInventory(CInv(MSG_BLOCK, hash));
|
||||
}
|
||||
@@ -2558,37 +2551,40 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
|
||||
// Skip block signature verification during initial block download (below checkpoint).
|
||||
// The hardcoded checkpoint guarantees historical chain integrity.
|
||||
if (!pblock->CheckBlock(true, true, !IsInitialBlockDownload()))
|
||||
return error("ProcessBlock() : CheckBlock FAILED");
|
||||
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
|
||||
|
||||
if(pcheckpoint && fDebug)
|
||||
{
|
||||
const CBlockIndex* pindexLastPos = GetLastBlockIndex(pcheckpoint, true);
|
||||
if(pindexLastPos)
|
||||
{
|
||||
printf("ProcessBlock(): Last POS Block Height: %d \n", pindexLastPos->nHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ProcessBlock(): Previous POS block not found.\n");
|
||||
}
|
||||
printf("IBD-DIAG: CheckBlock FAILED for %s (PoS=%d, IBD=%d)\n",
|
||||
hash.ToString().substr(0,20).c_str(), pblock->IsProofOfStake(), IsInitialBlockDownload());
|
||||
return error("ProcessBlock() : CheckBlock FAILED");
|
||||
}
|
||||
|
||||
// Anti-spam: reject blocks with insufficient difficulty to prevent memory flooding.
|
||||
// Use sync checkpoint as reference; fall back to chain tip if checkpoint is genesis.
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
|
||||
if (!pcheckpoint || pcheckpoint->nHeight == 0)
|
||||
pcheckpoint = pindexBest;
|
||||
|
||||
if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
|
||||
{
|
||||
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
|
||||
int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
|
||||
CBigNum bnNewBlock;
|
||||
bnNewBlock.SetCompact(pblock->nBits);
|
||||
CBigNum bnRequired;
|
||||
|
||||
if (pblock->IsProofOfStake())
|
||||
bnRequired.SetCompact(ComputeMinStake(GetLastBlockIndex(pcheckpoint, true)->nBits, deltaTime, pblock->nTime));
|
||||
{
|
||||
const CBlockIndex* pindexLastPos = GetLastBlockIndex(pcheckpoint, true);
|
||||
if (pindexLastPos)
|
||||
bnRequired.SetCompact(ComputeMinStake(pindexLastPos->nBits, deltaTime, pblock->nTime));
|
||||
// else: no PoS history yet (below block 9001), skip — AcceptBlock rejects PoS below MODIFIER_INTERVAL_SWITCH
|
||||
}
|
||||
else
|
||||
bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, false)->nBits, deltaTime));
|
||||
{
|
||||
const CBlockIndex* pindexLastPow = GetLastBlockIndex(pcheckpoint, false);
|
||||
if (pindexLastPow)
|
||||
bnRequired.SetCompact(ComputeMinWork(pindexLastPow->nBits, deltaTime));
|
||||
}
|
||||
|
||||
if (bnNewBlock > bnRequired)
|
||||
if (bnRequired != 0 && bnNewBlock > bnRequired)
|
||||
{
|
||||
if (pfrom)
|
||||
pfrom->Misbehaving(100);
|
||||
@@ -2618,6 +2614,31 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
|
||||
mapOrphanBlocks.insert(make_pair(hash, pblock2));
|
||||
mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
|
||||
|
||||
// Limit orphan blocks to prevent memory exhaustion
|
||||
if (mapOrphanBlocks.size() > MAX_ORPHAN_BLOCKS)
|
||||
{
|
||||
// Evict a random orphan
|
||||
uint256 randomhash = GetRandHash();
|
||||
auto it = mapOrphanBlocks.lower_bound(randomhash);
|
||||
if (it == mapOrphanBlocks.end())
|
||||
it = mapOrphanBlocks.begin();
|
||||
CBlock* pblockEvict = it->second;
|
||||
uint256 evictHash = it->first;
|
||||
// Remove from by-prev index
|
||||
for (auto range = mapOrphanBlocksByPrev.equal_range(pblockEvict->hashPrevBlock);
|
||||
range.first != range.second; ++range.first)
|
||||
{
|
||||
if (range.first->second == pblockEvict) {
|
||||
mapOrphanBlocksByPrev.erase(range.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
setStakeSeenOrphan.erase(pblockEvict->GetProofOfStake());
|
||||
delete pblockEvict;
|
||||
mapOrphanBlocks.erase(evictHash);
|
||||
printf("ProcessBlock: orphan eviction, %u orphans remain\n", (unsigned int)mapOrphanBlocks.size());
|
||||
}
|
||||
|
||||
// Ask this guy to fill in what we're missing
|
||||
if (pfrom)
|
||||
{
|
||||
@@ -3098,7 +3119,7 @@ string GetWarnings(string strFor)
|
||||
// Alerts
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||
for (auto& item : mapAlerts)
|
||||
{
|
||||
const CAlert& alert = item.second;
|
||||
if (alert.AppliesToMe() && alert.nPriority > nPriority)
|
||||
@@ -3270,29 +3291,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
// Ask connected nodes for block updates
|
||||
// During IBD, always request blocks from any valid peer (critical for reconnection)
|
||||
static int nAskedForBlocks = 0;
|
||||
if (!pfrom->fClient && !pfrom->fOneShot &&
|
||||
bool fShouldAsk = !pfrom->fClient && !pfrom->fOneShot &&
|
||||
(pfrom->nStartingHeight > (nBestHeight - 144)) &&
|
||||
(pfrom->nVersion < NOBLKS_VERSION_START ||
|
||||
pfrom->nVersion >= NOBLKS_VERSION_END) &&
|
||||
(IsInitialBlockDownload() || nAskedForBlocks < 1 || vNodes.size() <= 1))
|
||||
(IsInitialBlockDownload() || nAskedForBlocks < 1 || vNodes.size() <= 1);
|
||||
printf("IBD-DIAG: version handler: peer=%s height=%d ourHeight=%d fClient=%d fOneShot=%d shouldAsk=%d nAskedForBlocks=%d IBD=%d\n",
|
||||
pfrom->addr.ToString().c_str(), pfrom->nStartingHeight, nBestHeight,
|
||||
pfrom->fClient, pfrom->fOneShot, fShouldAsk, nAskedForBlocks, IsInitialBlockDownload());
|
||||
if (fShouldAsk)
|
||||
{
|
||||
nAskedForBlocks++;
|
||||
pfrom->PushGetBlocks(pindexBest, uint256(0));
|
||||
printf("IBD-DIAG: sent getblocks from height %d to peer %s\n", nBestHeight, pfrom->addr.ToString().c_str());
|
||||
}
|
||||
|
||||
// Relay alerts
|
||||
{
|
||||
LOCK(cs_mapAlerts);
|
||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||
for (auto& item : mapAlerts)
|
||||
item.second.RelayTo(pfrom);
|
||||
}
|
||||
|
||||
// triangles: relay sync-checkpoint
|
||||
{
|
||||
LOCK(Checkpoints::cs_hashSyncCheckpoint);
|
||||
if (!Checkpoints::checkpointMessage.IsNull())
|
||||
Checkpoints::checkpointMessage.RelayTo(pfrom);
|
||||
}
|
||||
// Sync checkpoint relay disabled (master key removed in V5 fork).
|
||||
// Relaying stale checkpoints causes IBD nodes to request far-future blocks.
|
||||
|
||||
pfrom->fSuccessfullyConnected = true;
|
||||
|
||||
@@ -3338,7 +3360,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
vector<CAddress> vAddrOk;
|
||||
int64_t nNow = GetAdjustedTime();
|
||||
int64_t nSince = nNow - 10 * 60;
|
||||
BOOST_FOREACH(CAddress& addr, vAddr)
|
||||
for (CAddress& addr : vAddr)
|
||||
{
|
||||
if (fShutdown)
|
||||
return true;
|
||||
@@ -3360,7 +3382,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
|
||||
hashRand = Hash(BEGIN(hashRand), END(hashRand));
|
||||
multimap<uint256, CNode*> mapMix;
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (pnode->nVersion < CADDR_TIME_VERSION)
|
||||
continue;
|
||||
@@ -3398,13 +3420,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
|
||||
// find last block in inv vector
|
||||
unsigned int nLastBlock = (unsigned int)(-1);
|
||||
int nBlockInv = 0, nTxInv = 0;
|
||||
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) {
|
||||
if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) {
|
||||
if (vInv[nInv].type == MSG_BLOCK) nBlockInv++;
|
||||
else nTxInv++;
|
||||
if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK && nLastBlock == (unsigned int)(-1)) {
|
||||
nLastBlock = vInv.size() - 1 - nInv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("IBD-DIAG: inv received: %d blocks, %d tx from %s (our height=%d)\n",
|
||||
nBlockInv, nTxInv, pfrom->addr.ToString().c_str(), nBestHeight);
|
||||
|
||||
CTxDB txdb("r");
|
||||
int nNew = 0, nAlready = 0;
|
||||
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
|
||||
{
|
||||
const CInv &inv = vInv[nInv];
|
||||
@@ -3414,25 +3442,24 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
|
||||
bool fAlreadyHave = AlreadyHave(txdb, inv);
|
||||
if (fDebug)
|
||||
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
|
||||
if (inv.type == MSG_BLOCK) {
|
||||
if (fAlreadyHave) nAlready++; else nNew++;
|
||||
}
|
||||
|
||||
if (!fAlreadyHave)
|
||||
pfrom->AskFor(inv);
|
||||
else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
|
||||
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
|
||||
} else if (nInv == nLastBlock) {
|
||||
// In case we are on a very long side-chain, it is possible that we already have
|
||||
// the last block in an inv bundle sent in response to getblocks. Try to detect
|
||||
// this situation and push another getblocks to continue.
|
||||
pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
|
||||
if (fDebug)
|
||||
printf("force request: %s\n", inv.ToString().c_str());
|
||||
printf("IBD-DIAG: inv last block already known, pushing getblocks from %d\n",
|
||||
mapBlockIndex[inv.hash]->nHeight);
|
||||
}
|
||||
|
||||
// Track requests for our stuff
|
||||
Inventory(inv.hash);
|
||||
}
|
||||
if (nBlockInv > 0)
|
||||
printf("IBD-DIAG: inv result: %d new blocks requested, %d already have\n", nNew, nAlready);
|
||||
}
|
||||
|
||||
|
||||
@@ -3449,7 +3476,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
if (fDebugNet || (vInv.size() != 1))
|
||||
printf("received getdata (%"PRIszu" invsz)\n", vInv.size());
|
||||
|
||||
BOOST_FOREACH(const CInv& inv, vInv)
|
||||
for (const CInv& inv : vInv)
|
||||
{
|
||||
if (fShutdown)
|
||||
return true;
|
||||
@@ -3522,7 +3549,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
if (pindex)
|
||||
pindex = pindex->pnext;
|
||||
int nLimit = IsInitialBlockDownload() ? 20000 : 500;
|
||||
printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
|
||||
printf("IBD-DIAG: getblocks request from peer %s: start=%d stop=%s limit=%d\n",
|
||||
pfrom->addr.ToString().c_str(), (pindex ? pindex->nHeight : -1),
|
||||
hashStop.ToString().substr(0,20).c_str(), nLimit);
|
||||
for (; pindex; pindex = pindex->pnext)
|
||||
{
|
||||
if (pindex->GetBlockHash() == hashStop)
|
||||
@@ -3547,17 +3576,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
}
|
||||
else if (strCommand == "checkpoint")
|
||||
{
|
||||
CSyncCheckpoint checkpoint;
|
||||
vRecv >> checkpoint;
|
||||
|
||||
if (checkpoint.ProcessSyncCheckpoint(pfrom))
|
||||
{
|
||||
// Relay
|
||||
pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint;
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
checkpoint.RelayTo(pnode);
|
||||
}
|
||||
// Sync checkpoint system disabled (master key removed in V5 fork).
|
||||
// Ignore checkpoint messages — processing them during IBD causes the
|
||||
// node to request a single far-future block instead of syncing sequentially.
|
||||
}
|
||||
|
||||
else if (strCommand == "getheaders")
|
||||
@@ -3608,7 +3629,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
CTxDB txdb("r");
|
||||
uint256 hashChainTip = 0;
|
||||
int nRequested = 0;
|
||||
BOOST_FOREACH(const CBlock& header, vHeaders)
|
||||
for (const CBlock& header : vHeaders)
|
||||
{
|
||||
if (!header.vtx.empty())
|
||||
{
|
||||
@@ -3709,7 +3730,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(uint256 hash, vEraseQueue)
|
||||
for (uint256 hash : vEraseQueue)
|
||||
EraseOrphanTx(hash);
|
||||
}
|
||||
else if (fMissingInputs)
|
||||
@@ -3731,9 +3752,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
vRecv >> block;
|
||||
uint256 hashBlock = block.GetHash();
|
||||
|
||||
if (!IsInitialBlockDownload())
|
||||
printf("received block %s\n", hashBlock.ToString().substr(0,20).c_str());
|
||||
// block.print();
|
||||
// Log every block during IBD (with throttling after first 100)
|
||||
static int64_t nLastBlockLog = 0;
|
||||
static int nBlocksReceived = 0;
|
||||
nBlocksReceived++;
|
||||
bool fLogThis = (nBlocksReceived <= 20) || (nBestHeight % 500 == 0) || !IsInitialBlockDownload() || (GetTime() - nLastBlockLog >= 5);
|
||||
if (fLogThis) {
|
||||
printf("IBD-DIAG: block received #%d hash=%s from=%s ourHeight=%d\n",
|
||||
nBlocksReceived, hashBlock.ToString().substr(0,20).c_str(),
|
||||
pfrom->addr.ToString().c_str(), nBestHeight);
|
||||
nLastBlockLog = GetTime();
|
||||
}
|
||||
|
||||
CInv inv(MSG_BLOCK, hashBlock);
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
@@ -3742,22 +3771,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
{
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
|
||||
// During IBD, proactively request more blocks to keep the pipeline full.
|
||||
// With assumevalid, blocks process near-instantly, so request aggressively.
|
||||
if (IsInitialBlockDownload())
|
||||
{
|
||||
static int nBlocksSinceRequest = 0;
|
||||
if (++nBlocksSinceRequest >= 100)
|
||||
if (++nBlocksSinceRequest >= 1000)
|
||||
{
|
||||
nBlocksSinceRequest = 0;
|
||||
pfrom->pindexLastGetBlocksBegin = NULL; // clear dedup filter
|
||||
pfrom->pindexLastGetBlocksBegin = NULL;
|
||||
pfrom->PushGetBlocks(pindexBest, uint256(0));
|
||||
printf("IBD-DIAG: pipeline refill at height %d\n", nBestHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("IBD-DIAG: ProcessBlock FAILED for block %s (height after prev=%d, DoS=%d)\n",
|
||||
hashBlock.ToString().substr(0,20).c_str(), nBestHeight, block.nDoS);
|
||||
}
|
||||
|
||||
if (block.nDoS)
|
||||
if (block.nDoS) {
|
||||
printf("IBD-DIAG: Misbehaving peer %s by %d\n",
|
||||
pfrom->addr.ToString().c_str(), block.nDoS);
|
||||
pfrom->Misbehaving(block.nDoS);
|
||||
}
|
||||
|
||||
if (fSecMsgEnabled && !IsInitialBlockDownload())
|
||||
SecureMsgScanBlock(block);
|
||||
@@ -3770,7 +3806,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
int64_t nCutOff = GetTime() - (nNodeLifespan * 24 * 60 * 60);
|
||||
pfrom->vAddrToSend.clear();
|
||||
vector<CAddress> vAddr = addrman.GetAddr();
|
||||
BOOST_FOREACH(const CAddress &addr, vAddr)
|
||||
for (const CAddress &addr : vAddr)
|
||||
if(addr.nTime > nCutOff)
|
||||
pfrom->PushAddress(addr);
|
||||
}
|
||||
@@ -3875,7 +3911,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
pfrom->setKnown.insert(alertHash);
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
alert.RelayTo(pnode);
|
||||
}
|
||||
}
|
||||
@@ -4090,7 +4126,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
{
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
// Periodically clear setAddrKnown to allow refresh broadcasts
|
||||
if (nLastRebroadcast)
|
||||
@@ -4115,7 +4151,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
{
|
||||
vector<CAddress> vAddr;
|
||||
vAddr.reserve(pto->vAddrToSend.size());
|
||||
BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
|
||||
for (const CAddress& addr : pto->vAddrToSend)
|
||||
{
|
||||
// returns true if wasn't already contained in the set
|
||||
if (pto->setAddrKnown.insert(addr).second)
|
||||
@@ -4144,7 +4180,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
LOCK(pto->cs_inventory);
|
||||
vInv.reserve(pto->vInventoryToSend.size());
|
||||
vInvWait.reserve(pto->vInventoryToSend.size());
|
||||
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
|
||||
for (const CInv& inv : pto->vInventoryToSend)
|
||||
{
|
||||
if (pto->setInventoryKnown.count(inv))
|
||||
continue;
|
||||
@@ -4194,27 +4230,43 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
|
||||
|
||||
//
|
||||
// Stall detection: if IBD and no new blocks for 30 seconds, re-request
|
||||
// Stall detection: if IBD and no new blocks for 5 seconds, re-request
|
||||
//
|
||||
if (IsInitialBlockDownload() && !pto->fClient)
|
||||
{
|
||||
static int64_t nLastBlockReceived = 0;
|
||||
static int nLastHeight = 0;
|
||||
static int64_t nLastStallLog = 0;
|
||||
if (nBestHeight > nLastHeight) {
|
||||
nLastHeight = nBestHeight;
|
||||
nLastBlockReceived = GetTime();
|
||||
} else if (nLastBlockReceived > 0 && GetTime() - nLastBlockReceived > 5) {
|
||||
printf("IBD stall detected at height %d, re-requesting blocks\n", nBestHeight);
|
||||
// Clear dedup filter so the request actually sends
|
||||
} else if (nLastBlockReceived > 0 && GetTime() - nLastBlockReceived > 2) {
|
||||
if (GetTime() - nLastStallLog >= 10) { // log every 10s max
|
||||
printf("IBD-DIAG: STALL at height %d for %ds, peer=%s askfor_queue=%d send_size=%d\n",
|
||||
nBestHeight, (int)(GetTime() - nLastBlockReceived),
|
||||
pto->addr.ToString().c_str(),
|
||||
(int)pto->mapAskFor.size(), (int)pto->nSendSize);
|
||||
nLastStallLog = GetTime();
|
||||
}
|
||||
pto->pindexLastGetBlocksBegin = NULL;
|
||||
pto->PushGetBlocks(pindexBest, uint256(0));
|
||||
nLastBlockReceived = GetTime(); // reset timer
|
||||
nLastBlockReceived = GetTime();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Message: getdata
|
||||
//
|
||||
// Periodic IBD status
|
||||
if (IsInitialBlockDownload()) {
|
||||
static int64_t nLastStatus = 0;
|
||||
if (GetTime() - nLastStatus >= 15) {
|
||||
printf("IBD-DIAG: STATUS height=%d peers=%d askfor_queued=%d orphans=%d\n",
|
||||
nBestHeight, (int)vNodes.size(), (int)pto->mapAskFor.size(), (int)mapOrphanBlocks.size());
|
||||
nLastStatus = GetTime();
|
||||
}
|
||||
}
|
||||
|
||||
vector<CInv> vGetData;
|
||||
int64_t nNow = GetTime() * 1000000;
|
||||
CTxDB txdb("r");
|
||||
|
||||
+9
-8
@@ -34,6 +34,7 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
|
||||
static const unsigned int MAX_ORPHAN_BLOCKS = 750;
|
||||
static const unsigned int MAX_INV_SZ = 50000;
|
||||
static const int64_t MIN_TX_FEE = (1 * CENT) / 100;
|
||||
static const int64_t MIN_RELAY_TX_FEE = (1 * CENT) / 100;
|
||||
@@ -489,7 +490,7 @@ public:
|
||||
nBlockTime = GetAdjustedTime();
|
||||
if ((int64_t)nLockTime < ((int64_t)nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
|
||||
return true;
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
for (const CTxIn& txin : vin)
|
||||
if (!txin.IsFinal())
|
||||
return false;
|
||||
return true;
|
||||
@@ -567,7 +568,7 @@ public:
|
||||
int64_t GetValueOut() const
|
||||
{
|
||||
int64_t nValueOut = 0;
|
||||
BOOST_FOREACH(const CTxOut& txout, vout)
|
||||
for (const CTxOut& txout : vout)
|
||||
{
|
||||
nValueOut += txout.nValue;
|
||||
if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
|
||||
@@ -955,7 +956,7 @@ public:
|
||||
int64_t GetMaxTransactionTime() const
|
||||
{
|
||||
int64_t maxTransactionTime = 0;
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
maxTransactionTime = std::max(maxTransactionTime, (int64_t)tx.nTime);
|
||||
return maxTransactionTime;
|
||||
}
|
||||
@@ -963,7 +964,7 @@ public:
|
||||
uint256 BuildMerkleTree() const
|
||||
{
|
||||
vMerkleTree.clear();
|
||||
BOOST_FOREACH(const CTransaction& tx, vtx)
|
||||
for (const CTransaction& tx : vtx)
|
||||
vMerkleTree.push_back(tx.GetHash());
|
||||
int j = 0;
|
||||
for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
|
||||
@@ -999,7 +1000,7 @@ public:
|
||||
{
|
||||
if (nIndex == -1)
|
||||
return 0;
|
||||
BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
|
||||
for (const uint256& otherside : vMerkleBranch)
|
||||
{
|
||||
if (nIndex & 1)
|
||||
hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
|
||||
@@ -1518,7 +1519,7 @@ public:
|
||||
// Retrace how far back it was in the sender's branch
|
||||
int nDistance = 0;
|
||||
int nStep = 1;
|
||||
BOOST_FOREACH(const uint256& hash, vHave)
|
||||
for (const uint256& hash : vHave)
|
||||
{
|
||||
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
@@ -1537,7 +1538,7 @@ public:
|
||||
CBlockIndex* GetBlockIndex()
|
||||
{
|
||||
// Find the first block the caller has in the main chain
|
||||
BOOST_FOREACH(const uint256& hash, vHave)
|
||||
for (const uint256& hash : vHave)
|
||||
{
|
||||
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
@@ -1553,7 +1554,7 @@ public:
|
||||
uint256 GetBlockHash()
|
||||
{
|
||||
// Find the first block the caller has in the main chain
|
||||
BOOST_FOREACH(const uint256& hash, vHave)
|
||||
for (const uint256& hash : vHave)
|
||||
{
|
||||
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
|
||||
+26
-2
@@ -74,7 +74,7 @@ HARDENING+=-D_FORTIFY_SOURCE=2
|
||||
|
||||
DEBUGFLAGS=-g
|
||||
|
||||
xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
|
||||
xCXXFLAGS=-O2 -std=c++17 -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
|
||||
-Wno-deprecated-declarations -Wno-reserved-user-defined-literal \
|
||||
-Wa,-mbig-obj \
|
||||
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
|
||||
@@ -135,8 +135,11 @@ OBJS= \
|
||||
obj/scrypt-x86.o \
|
||||
obj/scrypt-x86_64.o \
|
||||
obj/smessage.o \
|
||||
obj/lz4.o \
|
||||
obj/onion_v3.o \
|
||||
obj/tor_process.o
|
||||
obj/tor_process.o \
|
||||
obj/tor_embed_hooks.o \
|
||||
obj/tor_embedded.o
|
||||
|
||||
all: trianglesd.exe
|
||||
|
||||
@@ -208,6 +211,27 @@ obj/tor_process.o: tor/tor_process.cpp
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/lz4.o: lz4/lz4.c
|
||||
$(CXX) -c $(xCXXFLAGS) -fpermissive -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/tor_embed_hooks.o: tor_embed_hooks.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/tor_embedded.o: tor/tor_embedded.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/net_bootstrap.o: net_bootstrap.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
|
||||
+32
-7
@@ -107,7 +107,7 @@ endif
|
||||
|
||||
# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
|
||||
# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
|
||||
xCXXFLAGS=-O2 $(EXT_OPTIONS) -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
|
||||
xCXXFLAGS=-O2 -std=c++17 $(EXT_OPTIONS) -pthread -Wall -Wextra -Wno-ignored-qualifiers -Wformat -Wformat-security -Wno-unused-parameter \
|
||||
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
|
||||
|
||||
# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only
|
||||
@@ -170,8 +170,26 @@ OBJS= \
|
||||
obj/scrypt-x86.o \
|
||||
obj/scrypt-x86_64.o \
|
||||
obj/smessage.o \
|
||||
obj/lz4.o \
|
||||
obj/onion_v3.o \
|
||||
obj/tor_process.o
|
||||
obj/tor_process.o \
|
||||
obj/tor_embed_hooks.o \
|
||||
obj/tor_embedded.o
|
||||
|
||||
# Embedded Tor support (optional)
|
||||
# Build with: make -f makefile.unix USE_TOR_EMBEDDED=1 TOR_SOURCE_ROOT=/path/to/tor-src
|
||||
# Requires libtor.a built from official Tor source (see CODEX-TOR-GUIDE.md)
|
||||
TOR_SOURCE_ROOT ?= tor/tor-src
|
||||
TOR_INCLUDE_PATH ?= $(TOR_SOURCE_ROOT)/src/feature/api
|
||||
TOR_LIB_PATH ?= $(TOR_SOURCE_ROOT)
|
||||
TOR_EMBEDDED_LIBS ?= -ltor
|
||||
ifdef USE_TOR_EMBEDDED
|
||||
DEFS += -DENABLE_TOR_EMBEDDED
|
||||
DEFS += $(addprefix -I,$(TOR_INCLUDE_PATH))
|
||||
LIBS += $(addprefix -L,$(TOR_LIB_PATH))
|
||||
LIBS += -Wl,--start-group $(TOR_EMBEDDED_LIBS) -Wl,--end-group
|
||||
LIBS += -llzma -lzstd -lm -lpthread
|
||||
endif
|
||||
|
||||
# ZMQ support (optional)
|
||||
# Build with: make -f makefile.unix USE_ZMQ=1
|
||||
@@ -226,14 +244,14 @@ obj/%.o: %.c
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/%.o: tor/%.c
|
||||
$(CC) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
obj/lz4.o: lz4/lz4.c
|
||||
$(CXX) -c $(xCXXFLAGS) -fpermissive -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//'\
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/anonymize.o: tor/anonymize.cpp
|
||||
obj/tor_embed_hooks.o: tor_embed_hooks.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
@@ -254,6 +272,13 @@ obj/tor_process.o: tor/tor_process.cpp
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/tor_embedded.o: tor/tor_embedded.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
obj/net_bootstrap.o: net_bootstrap.cpp
|
||||
$(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $<
|
||||
@cp $(@:%.o=%.d) $(@:%.o=%.P); \
|
||||
@@ -261,7 +286,7 @@ obj/net_bootstrap.o: net_bootstrap.cpp
|
||||
-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
|
||||
rm -f $(@:%.o=%.d)
|
||||
|
||||
trianglesd: $(OBJS:obj/%=obj/%) obj/anonymize.o
|
||||
trianglesd: $(OBJS:obj/%=obj/%)
|
||||
$(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS)
|
||||
|
||||
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
|
||||
|
||||
+15
-15
@@ -72,7 +72,7 @@ public:
|
||||
{
|
||||
printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n",
|
||||
ptx->GetHash().ToString().substr(0,10).c_str(), dPriority, dFeePerKb);
|
||||
BOOST_FOREACH(uint256 hash, setDependsOn)
|
||||
for (uint256 hash : setDependsOn)
|
||||
printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
|
||||
}
|
||||
};
|
||||
@@ -83,7 +83,7 @@ uint64_t nLastBlockSize = 0;
|
||||
int64_t nLastCoinStakeSearchInterval = 0;
|
||||
|
||||
// We want to sort transactions by priority and fee, so:
|
||||
typedef boost::tuple<double, double, CTransaction*> TxPriority;
|
||||
typedef std::tuple<double, double, CTransaction*> TxPriority;
|
||||
class TxPriorityCompare
|
||||
{
|
||||
bool byFee;
|
||||
@@ -93,15 +93,15 @@ public:
|
||||
{
|
||||
if (byFee)
|
||||
{
|
||||
if (a.get<1>() == b.get<1>())
|
||||
return a.get<0>() < b.get<0>();
|
||||
return a.get<1>() < b.get<1>();
|
||||
if (std::get<1>(a) == std::get<1>(b))
|
||||
return std::get<0>(a) < std::get<0>(b);
|
||||
return std::get<1>(a) < std::get<1>(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a.get<0>() == b.get<0>())
|
||||
return a.get<1>() < b.get<1>();
|
||||
return a.get<0>() < b.get<0>();
|
||||
if (std::get<0>(a) == std::get<0>(b))
|
||||
return std::get<1>(a) < std::get<1>(b);
|
||||
return std::get<0>(a) < std::get<0>(b);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
{
|
||||
// Create new block
|
||||
auto_ptr<CBlock> pblock(new CBlock());
|
||||
unique_ptr<CBlock> pblock(new CBlock());
|
||||
if (!pblock.get())
|
||||
return NULL;
|
||||
|
||||
@@ -188,7 +188,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
double dPriority = 0;
|
||||
int64_t nTotalIn = 0;
|
||||
bool fMissingInputs = false;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
// Read prev transaction
|
||||
CTransaction txPrev;
|
||||
@@ -259,9 +259,9 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
while (!vecPriority.empty())
|
||||
{
|
||||
// Take highest priority transaction off the priority queue:
|
||||
double dPriority = vecPriority.front().get<0>();
|
||||
double dFeePerKb = vecPriority.front().get<1>();
|
||||
CTransaction& tx = *(vecPriority.front().get<2>());
|
||||
double dPriority = std::get<0>(vecPriority.front());
|
||||
double dFeePerKb = std::get<1>(vecPriority.front());
|
||||
CTransaction& tx = *(std::get<2>(vecPriority.front()));
|
||||
|
||||
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||
vecPriority.pop_back();
|
||||
@@ -335,7 +335,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
uint256 hash = tx.GetHash();
|
||||
if (mapDependers.count(hash))
|
||||
{
|
||||
BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
|
||||
for (COrphan* porphan : mapDependers[hash])
|
||||
{
|
||||
if (!porphan->setDependsOn.empty())
|
||||
{
|
||||
@@ -562,7 +562,7 @@ void StakeMiner(CWallet *pwallet)
|
||||
// Create new block
|
||||
//
|
||||
int64_t nFees;
|
||||
auto_ptr<CBlock> pblock(CreateNewBlock(pwallet, true, &nFees));
|
||||
unique_ptr<CBlock> pblock(CreateNewBlock(pwallet, true, &nFees));
|
||||
if (!pblock.get())
|
||||
return;
|
||||
|
||||
|
||||
+31
-32
@@ -213,7 +213,7 @@ bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
void static AdvertizeLocal()
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (pnode->fSuccessfullyConnected)
|
||||
{
|
||||
@@ -458,7 +458,7 @@ CNode* FindNode(const CNetAddr& ip)
|
||||
{
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if ((CNetAddr)pnode->addr == ip)
|
||||
return (pnode);
|
||||
}
|
||||
@@ -468,7 +468,7 @@ CNode* FindNode(const CNetAddr& ip)
|
||||
CNode* FindNode(std::string addrName)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if (pnode->addrName == addrName)
|
||||
return (pnode);
|
||||
return NULL;
|
||||
@@ -478,7 +478,7 @@ CNode* FindNode(const CService& addr)
|
||||
{
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if ((CService)pnode->addr == addr)
|
||||
return (pnode);
|
||||
}
|
||||
@@ -823,7 +823,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
LOCK(cs_vNodes);
|
||||
// Disconnect unused nodes
|
||||
vector<CNode*> vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
{
|
||||
if (pnode->fDisconnect ||
|
||||
(pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
|
||||
@@ -847,7 +847,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
|
||||
// Delete disconnected nodes
|
||||
list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
|
||||
for (CNode* pnode : vNodesDisconnectedCopy)
|
||||
{
|
||||
// wait until threads are done using it
|
||||
if (pnode->GetRefCount() <= 0)
|
||||
@@ -890,7 +890,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
//
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = IsInitialBlockDownload() ? 10000 : 50000; // faster polling during IBD
|
||||
timeout.tv_usec = IsInitialBlockDownload() ? 1000 : 50000; // 1ms during IBD, 50ms normal
|
||||
|
||||
fd_set fdsetRecv;
|
||||
fd_set fdsetSend;
|
||||
@@ -901,14 +901,14 @@ void ThreadSocketHandler2(void* parg)
|
||||
SOCKET hSocketMax = 0;
|
||||
bool have_fds = false;
|
||||
|
||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
|
||||
for (SOCKET hListenSocket : vhListenSocket) {
|
||||
FD_SET(hListenSocket, &fdsetRecv);
|
||||
hSocketMax = max(hSocketMax, hListenSocket);
|
||||
have_fds = true;
|
||||
}
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (pnode->hSocket == INVALID_SOCKET)
|
||||
continue;
|
||||
@@ -948,7 +948,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
//
|
||||
// Accept new connections
|
||||
//
|
||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||
for (SOCKET hListenSocket : vhListenSocket)
|
||||
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
@@ -967,7 +967,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if (pnode->fInbound)
|
||||
nInbound++;
|
||||
}
|
||||
@@ -1007,10 +1007,10 @@ void ThreadSocketHandler2(void* parg)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
pnode->AddRef();
|
||||
}
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
{
|
||||
if (fShutdown)
|
||||
return;
|
||||
@@ -1100,7 +1100,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
}
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
pnode->Release();
|
||||
}
|
||||
|
||||
@@ -1439,7 +1439,7 @@ void ThreadDNSAddressSeed2(void* parg)
|
||||
vector<CNetAddr> vaddr;
|
||||
if (LookupHost(strDNSSeed[seed_idx], vaddr))
|
||||
{
|
||||
BOOST_FOREACH(CNetAddr& ip, vaddr)
|
||||
for (CNetAddr& ip : vaddr)
|
||||
{
|
||||
CAddress addr(CService(ip, GetDefaultPort()));
|
||||
addr.nTime = GetTime() - 3*24*60*60; // 3 days ago
|
||||
@@ -1541,7 +1541,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
for (int64_t nLoop = 0;; nLoop++)
|
||||
{
|
||||
ProcessOneShot();
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
|
||||
for (string strAddr : mapMultiArgs["-connect"])
|
||||
{
|
||||
CAddress addr;
|
||||
OpenNetworkConnection(addr, NULL, strAddr.c_str());
|
||||
@@ -1581,7 +1581,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
bool fNoOutbound = true;
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
for (CNode* pnode : vNodes) {
|
||||
if (!pnode->fInbound) { fNoOutbound = false; break; }
|
||||
}
|
||||
if (fNoOutbound && (GetTime() - nStart > 30) && !fTestNet)
|
||||
@@ -1611,7 +1611,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
set<vector<unsigned char> > setConnected;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
for (CNode* pnode : vNodes) {
|
||||
if (!pnode->fInbound) {
|
||||
setConnected.insert(pnode->addr.GetGroup());
|
||||
nOutbound++;
|
||||
@@ -1688,7 +1688,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
|
||||
if (HaveNameProxy()) {
|
||||
while(!fShutdown) {
|
||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
|
||||
for (string& strAddNode : mapMultiArgs["-addnode"]) {
|
||||
CAddress addr;
|
||||
CSemaphoreGrant grant(*semOutbound);
|
||||
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
|
||||
@@ -1702,7 +1702,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
}
|
||||
|
||||
vector<vector<CService> > vservAddressesToAdd(0);
|
||||
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
|
||||
for (string& strAddNode : mapMultiArgs["-addnode"])
|
||||
{
|
||||
vector<CService> vservNode(0);
|
||||
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
|
||||
@@ -1710,7 +1710,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
vservAddressesToAdd.push_back(vservNode);
|
||||
{
|
||||
LOCK(cs_setservAddNodeAddresses);
|
||||
BOOST_FOREACH(CService& serv, vservNode)
|
||||
for (CService& serv : vservNode)
|
||||
setservAddNodeAddresses.insert(serv);
|
||||
}
|
||||
}
|
||||
@@ -1722,9 +1722,9 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
// (keeping in mind that addnode entries can have many IPs if fNameLookup)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
|
||||
BOOST_FOREACH(CService& addrNode, *(it))
|
||||
for (CService& addrNode : *(it))
|
||||
if (pnode->addr == addrNode)
|
||||
{
|
||||
it = vservConnectAddresses.erase(it);
|
||||
@@ -1732,7 +1732,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||
break;
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
||||
for (vector<CService>& vserv : vservConnectAddresses)
|
||||
{
|
||||
CSemaphoreGrant grant(*semOutbound);
|
||||
OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
|
||||
@@ -1822,7 +1822,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
pnode->AddRef();
|
||||
}
|
||||
|
||||
@@ -1830,7 +1830,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
CNode* pnodeTrickle = NULL;
|
||||
if (!vNodesCopy.empty())
|
||||
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
{
|
||||
// Receive messages
|
||||
{
|
||||
@@ -1854,7 +1854,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
pnode->Release();
|
||||
}
|
||||
|
||||
@@ -1872,7 +1872,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
// Reduce vnThreadsRunning so StopNode has permission to exit while
|
||||
// we're sleeping, but we must always check fShutdown after doing this.
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
|
||||
MilliSleep(IsInitialBlockDownload() ? 10 : 100);
|
||||
MilliSleep(IsInitialBlockDownload() ? 1 : 100);
|
||||
if (fRequestShutdown)
|
||||
StartShutdown();
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
|
||||
@@ -2027,7 +2027,7 @@ static void run_tor() {
|
||||
// which starts an external Tor binary with SOCKS5 proxy and v3 hidden service.
|
||||
// The old embedded Tor v2 code was removed (incompatible with OpenSSL 3.x).
|
||||
printf("Tor v3 mode: using managed Tor process via SOCKS5 proxy.\n");
|
||||
set_initialized();
|
||||
triangles_tor_set_initialized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2192,10 +2192,10 @@ public:
|
||||
~CNetCleanup()
|
||||
{
|
||||
// Close sockets
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
if (pnode->hSocket != INVALID_SOCKET)
|
||||
closesocket(pnode->hSocket);
|
||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||
for (SOCKET hListenSocket : vhListenSocket)
|
||||
if (hListenSocket != INVALID_SOCKET)
|
||||
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
||||
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
||||
@@ -2235,4 +2235,3 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
|
||||
|
||||
RelayInventory(inv);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <deque>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -27,8 +26,8 @@ extern int nBestHeight;
|
||||
|
||||
|
||||
|
||||
inline unsigned int ReceiveFloodSize() { return (unsigned int)-1; }
|
||||
inline unsigned int SendBufferSize() { return (unsigned int)-1; }
|
||||
inline unsigned int ReceiveFloodSize() { return 100 * 1024 * 1024; } // 100 MB
|
||||
inline unsigned int SendBufferSize() { return 32 * 1024 * 1024; } // 32 MB
|
||||
|
||||
void AddOneShot(std::string strDest);
|
||||
bool RecvLine(SOCKET hSocket, std::string& strLine);
|
||||
@@ -325,8 +324,10 @@ public:
|
||||
|
||||
// Be shy and don't send version until we hear
|
||||
if (hSocket != INVALID_SOCKET && !fInbound)
|
||||
{
|
||||
printf("CNode(): pfrom-addr %s\n", addrName.c_str());
|
||||
PushVersion();
|
||||
}
|
||||
}
|
||||
|
||||
~CNode()
|
||||
@@ -354,7 +355,7 @@ public:
|
||||
unsigned int GetTotalRecvSize()
|
||||
{
|
||||
unsigned int total = 0;
|
||||
BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
|
||||
for (const CNetMessage &msg : vRecvMsg)
|
||||
total += msg.vRecv.size() + 24;
|
||||
return total;
|
||||
}
|
||||
@@ -366,7 +367,7 @@ public:
|
||||
void SetRecvVersion(int nVersionIn)
|
||||
{
|
||||
nRecvVersion = nVersionIn;
|
||||
BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
|
||||
for (CNetMessage &msg : vRecvMsg)
|
||||
msg.SetVersion(nVersionIn);
|
||||
}
|
||||
|
||||
@@ -740,7 +741,7 @@ inline void RelayInventory(const CInv& inv)
|
||||
// Put on lists to offer to the other nodes
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
pnode->PushInventory(inv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef TRIANGLES_OPENSSL_COMPAT_H
|
||||
#define TRIANGLES_OPENSSL_COMPAT_H
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
static inline const char* TrianglesOpenSSLVersionString()
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
return OpenSSL_version(OPENSSL_VERSION);
|
||||
#else
|
||||
return SSLeay_version(SSLEAY_VERSION);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // TRIANGLES_OPENSSL_COMPAT_H
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "aboutdialog.h"
|
||||
#include "ui_aboutdialog.h"
|
||||
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "clientmodel.h"
|
||||
#include "dialog_move_handler.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
cachedAddressTable.clear();
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
|
||||
for (const auto& item : wallet->mapAddressBook)
|
||||
{
|
||||
const CTrianglesAddress& address = item.first;
|
||||
const std::string& strName = item.second;
|
||||
|
||||
@@ -506,7 +506,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
coinControl->ListSelected(vCoinControl);
|
||||
model->getOutputs(vCoinControl, vOutputs);
|
||||
|
||||
BOOST_FOREACH(const COutput& out, vOutputs)
|
||||
for (const COutput& out : vOutputs)
|
||||
{
|
||||
// Quantity
|
||||
nQuantity++;
|
||||
@@ -522,7 +522,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
|
||||
{
|
||||
CPubKey pubkey;
|
||||
CKeyID *keyid = boost::get< CKeyID >(&address);
|
||||
CKeyID *keyid = std::get_if< CKeyID >(&address);
|
||||
if (keyid && model->getPubKey(*keyid, pubkey))
|
||||
nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
|
||||
else
|
||||
@@ -647,7 +647,7 @@ void CoinControlDialog::updateView()
|
||||
map<QString, vector<COutput> > mapCoins;
|
||||
model->listCoins(mapCoins);
|
||||
|
||||
BOOST_FOREACH(PAIRTYPE(QString, vector<COutput>) coins, mapCoins)
|
||||
for (auto coins : mapCoins)
|
||||
{
|
||||
QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem();
|
||||
QString sWalletAddress = coins.first;
|
||||
@@ -679,7 +679,7 @@ void CoinControlDialog::updateView()
|
||||
double dPrioritySum = 0;
|
||||
int nChildren = 0;
|
||||
int nInputSum = 0;
|
||||
BOOST_FOREACH(const COutput& out, coins.second)
|
||||
for (const COutput& out : coins.second)
|
||||
{
|
||||
int nInputSize = 148; // 180 if uncompressed public key
|
||||
nSum += out.tx->vout[out.i].nValue;
|
||||
@@ -703,7 +703,7 @@ void CoinControlDialog::updateView()
|
||||
itemOutput->setText(COLUMN_ADDRESS, sAddress);
|
||||
|
||||
CPubKey pubkey;
|
||||
CKeyID *keyid = boost::get< CKeyID >(&outputAddress);
|
||||
CKeyID *keyid = std::get_if< CKeyID >(&outputAddress);
|
||||
if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed())
|
||||
nInputSize = 180;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ protected:
|
||||
|
||||
void MessageViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItemV4 optionV4 = option;
|
||||
QStyleOptionViewItem optionV4 = option;
|
||||
initStyleOption(&optionV4, index);
|
||||
|
||||
QStyle *style = optionV4.widget? optionV4.widget->style() : QApplication::style();
|
||||
@@ -62,7 +62,7 @@ void MessageViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o
|
||||
|
||||
QSize MessageViewDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
|
||||
{
|
||||
QStyleOptionViewItemV4 options = option;
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
QTextDocument doc;
|
||||
@@ -159,7 +159,7 @@ void MessagePage::setModel(MessageModel *model)
|
||||
// Set column widths
|
||||
ui->tableView->horizontalHeader()->resizeSection(MessageModel::Type, 100);
|
||||
ui->tableView->horizontalHeader()->resizeSection(MessageModel::Label, 100);
|
||||
ui->tableView->horizontalHeader()->setResizeMode(MessageModel::Label, QHeaderView::Stretch);
|
||||
ui->tableView->horizontalHeader()->setSectionResizeMode(MessageModel::Label, QHeaderView::Stretch);
|
||||
ui->tableView->horizontalHeader()->resizeSection(MessageModel::FromAddress, 320);
|
||||
ui->tableView->horizontalHeader()->resizeSection(MessageModel::ToAddress, 320);
|
||||
ui->tableView->horizontalHeader()->resizeSection(MessageModel::SentDateTime, 170);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "trianglesrpc.h"
|
||||
#include "guiutil.h"
|
||||
#include "dialog_move_handler.h"
|
||||
#include "openssl_compat.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
@@ -207,7 +208,7 @@ RPCConsole::RPCConsole(QWidget *parent) :
|
||||
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
|
||||
// set OpenSSL version label
|
||||
ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION));
|
||||
ui->openSSLVersion->setText(TrianglesOpenSSLVersionString());
|
||||
|
||||
startExecutor();
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
SignMessagePage::SignMessagePage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::SignMessagePage),
|
||||
|
||||
+10
-10
@@ -77,7 +77,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
if (nNet > 0)
|
||||
{
|
||||
// Credit
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
{
|
||||
if (wallet->IsMine(txout))
|
||||
{
|
||||
@@ -125,7 +125,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
// Coinbase
|
||||
//
|
||||
int64_t nUnmatured = 0;
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
nUnmatured += wallet->GetCredit(txout);
|
||||
strHTML += "<b>" + tr("Credit") + ":</b> ";
|
||||
if (wtx.IsInMainChain())
|
||||
@@ -144,11 +144,11 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
else
|
||||
{
|
||||
bool fAllFromMe = true;
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
for (const CTxIn& txin : wtx.vin)
|
||||
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
|
||||
|
||||
bool fAllToMe = true;
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
fAllToMe = fAllToMe && wallet->IsMine(txout);
|
||||
|
||||
if (fAllFromMe)
|
||||
@@ -156,7 +156,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
//
|
||||
// Debit
|
||||
//
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
{
|
||||
if (wallet->IsMine(txout))
|
||||
continue;
|
||||
@@ -196,10 +196,10 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
//
|
||||
// Mixed debit transaction
|
||||
//
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
for (const CTxIn& txin : wtx.vin)
|
||||
if (wallet->IsMine(txin))
|
||||
strHTML += "<b>" + tr("Debit") + ":</b> " + TrianglesUnits::formatWithUnit(TrianglesUnits::TRI, -wallet->GetDebit(txin)) + "<br>";
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
if (wallet->IsMine(txout))
|
||||
strHTML += "<b>" + tr("Credit") + ":</b> " + TrianglesUnits::formatWithUnit(TrianglesUnits::TRI, wallet->GetCredit(txout)) + "<br>";
|
||||
}
|
||||
@@ -234,10 +234,10 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
if (fDebug)
|
||||
{
|
||||
strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
for (const CTxIn& txin : wtx.vin)
|
||||
if(wallet->IsMine(txin))
|
||||
strHTML += "<b>" + tr("Debit") + ":</b> " + TrianglesUnits::formatWithUnit(TrianglesUnits::TRI, -wallet->GetDebit(txin)) + "<br>";
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
if(wallet->IsMine(txout))
|
||||
strHTML += "<b>" + tr("Credit") + ":</b> " + TrianglesUnits::formatWithUnit(TrianglesUnits::TRI, wallet->GetCredit(txout)) + "<br>";
|
||||
|
||||
@@ -251,7 +251,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
for (const CTxIn& txin : wtx.vin)
|
||||
{
|
||||
COutPoint prevout = txin.prevout;
|
||||
|
||||
|
||||
@@ -87,11 +87,11 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
|
||||
else
|
||||
{
|
||||
bool fAllFromMe = true;
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
for (const CTxIn& txin : wtx.vin)
|
||||
fAllFromMe = fAllFromMe && wallet->IsMine(txin);
|
||||
|
||||
bool fAllToMe = true;
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
fAllToMe = fAllToMe && wallet->IsMine(txout);
|
||||
|
||||
if (fAllFromMe && fAllToMe)
|
||||
|
||||
@@ -132,6 +132,14 @@ int main(int argc, char *argv[])
|
||||
// Command-line options take precedence:
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
// Application identification (must be set before IntroDialog uses QSettings)
|
||||
app.setOrganizationName("Triangles");
|
||||
//XXX app.setOrganizationDomain("");
|
||||
if(GetBoolArg("-testnet")) // Separate UI settings for testnet
|
||||
app.setApplicationName("Triangles-Qt-testnet");
|
||||
else
|
||||
app.setApplicationName("Triangles-Qt");
|
||||
|
||||
// Show data directory selection dialog on first run (unless -datadir was passed)
|
||||
if (!IntroDialog::pickDataDirectory())
|
||||
return 0;
|
||||
@@ -147,15 +155,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
|
||||
// Application identification (must be set before OptionsModel is initialized,
|
||||
// as it is used to locate QSettings)
|
||||
app.setOrganizationName("Triangles");
|
||||
//XXX app.setOrganizationDomain("");
|
||||
if(GetBoolArg("-testnet")) // Separate UI settings for testnet
|
||||
app.setApplicationName("Triangles-Qt-testnet");
|
||||
else
|
||||
app.setApplicationName("Triangles-Qt");
|
||||
|
||||
// ... then GUI settings:
|
||||
OptionsModel optionsModel;
|
||||
|
||||
@@ -220,6 +219,7 @@ int main(int argc, char *argv[])
|
||||
if (GUIUtil::GetStartOnSystemStartup())
|
||||
GUIUtil::SetStartOnSystemStartup(true);
|
||||
|
||||
InitMessage(_("Preparing interface..."));
|
||||
TrianglesGUI window;
|
||||
guiref = &window;
|
||||
if(AppInit2())
|
||||
|
||||
+102
-20
@@ -76,9 +76,10 @@
|
||||
#include <QTextStream>
|
||||
#include <QTextDocument>
|
||||
#include <QSettings>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGuiApplication>
|
||||
#include <QListWidget>
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
//#include <QSound>
|
||||
#include <QSizeGrip>
|
||||
|
||||
@@ -297,19 +298,15 @@ TrianglesGUI::TrianglesGUI(bool fIsTestnet, QWidget *parent):
|
||||
|
||||
receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
|
||||
|
||||
sendCoinsPage = new SendCoinsDialog(this);
|
||||
messagePage = new MessagePage(this);
|
||||
signMessagePage = new SignMessagePage(this);
|
||||
verifyMessagePage = new VerifyMessagePage(this);
|
||||
sendCoinsPage = 0;
|
||||
messagePage = 0;
|
||||
signMessagePage = 0;
|
||||
verifyMessagePage = 0;
|
||||
centralWidget = ui->stackedWidget;
|
||||
centralWidget->addWidget(overviewPage);
|
||||
centralWidget->addWidget(transactionsPage);
|
||||
centralWidget->addWidget(addressBookPage);
|
||||
centralWidget->addWidget(receiveCoinsPage);
|
||||
centralWidget->addWidget(sendCoinsPage);
|
||||
centralWidget->addWidget(messagePage);
|
||||
centralWidget->addWidget(signMessagePage);
|
||||
centralWidget->addWidget(verifyMessagePage);
|
||||
|
||||
QSizeGrip* grip = new QSizeGrip(this);
|
||||
grip->setStyleSheet("width: 6px; height: 6px; image: url(:/res/icons/handle.png);");
|
||||
@@ -337,6 +334,10 @@ TrianglesGUI::TrianglesGUI(bool fIsTestnet, QWidget *parent):
|
||||
updateStakingIcon();
|
||||
}
|
||||
|
||||
QTimer *timerShutdown = new QTimer(this);
|
||||
connect(timerShutdown, SIGNAL(timeout()), this, SLOT(detectShutdown()));
|
||||
timerShutdown->start(200);
|
||||
|
||||
// Progress bar and label for blocks download
|
||||
progressBarLabel = ui->label_synchronization;
|
||||
progressBarLabel->setVisible(false);
|
||||
@@ -359,8 +360,7 @@ TrianglesGUI::TrianglesGUI(bool fIsTestnet, QWidget *parent):
|
||||
// Double-clicking on a transaction on the transaction history page shows details
|
||||
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
|
||||
|
||||
rpcConsole = new RPCConsole(this);
|
||||
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
|
||||
connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(openRPCConsole()));
|
||||
|
||||
// Clicking on "Verify Message" in the address book sends you to the verify message tab
|
||||
connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
|
||||
@@ -479,7 +479,7 @@ void TrianglesGUI::createActions(bool fIsTestnet)
|
||||
openRPCConsoleAction = new QAction(QIcon(":/menu_16/debug"), tr("&Debug window"), this);
|
||||
openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
|
||||
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
connect(quitAction, SIGNAL(triggered()), this, SLOT(requestShutdown()));
|
||||
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
|
||||
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
||||
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
|
||||
@@ -563,7 +563,8 @@ void TrianglesGUI::setClientModel(ClientModel *clientModel)
|
||||
// Receive and report messages from network/worker thread
|
||||
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
|
||||
|
||||
rpcConsole->setClientModel(clientModel);
|
||||
if (rpcConsole)
|
||||
rpcConsole->setClientModel(clientModel);
|
||||
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
|
||||
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
|
||||
}
|
||||
@@ -582,9 +583,12 @@ void TrianglesGUI::setWalletModel(WalletModel *walletModel)
|
||||
overviewPage->setModel(walletModel);
|
||||
addressBookPage->setModel(walletModel->getAddressTableModel());
|
||||
receiveCoinsPage->setModel(walletModel->getAddressTableModel());
|
||||
sendCoinsPage->setModel(walletModel);
|
||||
signMessagePage->setModel(walletModel);
|
||||
verifyMessagePage->setModel(walletModel);
|
||||
if (sendCoinsPage)
|
||||
sendCoinsPage->setModel(walletModel);
|
||||
if (signMessagePage)
|
||||
signMessagePage->setModel(walletModel);
|
||||
if (verifyMessagePage)
|
||||
verifyMessagePage->setModel(walletModel);
|
||||
|
||||
setEncryptionStatus(walletModel->getEncryptionStatus());
|
||||
connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
|
||||
@@ -610,7 +614,8 @@ void TrianglesGUI::setMessageModel(MessageModel *messageModel)
|
||||
connect(messageModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));
|
||||
|
||||
// Put transaction list in tabs
|
||||
messagePage->setModel(messageModel);
|
||||
if (messagePage)
|
||||
messagePage->setModel(messageModel);
|
||||
|
||||
// Balloon pop-up for new message
|
||||
connect(messageModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
@@ -626,6 +631,60 @@ void TrianglesGUI::ensureMessageModel()
|
||||
setMessageModel(new MessageModel(pwalletMain, walletModel, this));
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureSendCoinsPage()
|
||||
{
|
||||
if (sendCoinsPage)
|
||||
return;
|
||||
|
||||
sendCoinsPage = new SendCoinsDialog(this);
|
||||
if (walletModel)
|
||||
sendCoinsPage->setModel(walletModel);
|
||||
centralWidget->addWidget(sendCoinsPage);
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureMessagePage()
|
||||
{
|
||||
if (messagePage)
|
||||
return;
|
||||
|
||||
messagePage = new MessagePage(this);
|
||||
if (messageModel)
|
||||
messagePage->setModel(messageModel);
|
||||
centralWidget->addWidget(messagePage);
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureSignMessagePage()
|
||||
{
|
||||
if (signMessagePage)
|
||||
return;
|
||||
|
||||
signMessagePage = new SignMessagePage(this);
|
||||
if (walletModel)
|
||||
signMessagePage->setModel(walletModel);
|
||||
centralWidget->addWidget(signMessagePage);
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureVerifyMessagePage()
|
||||
{
|
||||
if (verifyMessagePage)
|
||||
return;
|
||||
|
||||
verifyMessagePage = new VerifyMessagePage(this);
|
||||
if (walletModel)
|
||||
verifyMessagePage->setModel(walletModel);
|
||||
centralWidget->addWidget(verifyMessagePage);
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureRPCConsole()
|
||||
{
|
||||
if (rpcConsole)
|
||||
return;
|
||||
|
||||
rpcConsole = new RPCConsole(this);
|
||||
if (clientModel)
|
||||
rpcConsole->setClientModel(clientModel);
|
||||
}
|
||||
|
||||
void TrianglesGUI::createTrayIcon()
|
||||
{
|
||||
#ifndef Q_OS_MAC
|
||||
@@ -698,7 +757,8 @@ void TrianglesGUI::restoreWindowGeometry()
|
||||
QSize size = settings.value("nWindowSize", QSize(850, 550)).toSize();
|
||||
if (!pos.x() && !pos.y())
|
||||
{
|
||||
QRect screen = QApplication::desktop()->screenGeometry();
|
||||
QScreen *screenObject = QGuiApplication::primaryScreen();
|
||||
QRect screen = screenObject ? screenObject->availableGeometry() : QRect(QPoint(0, 0), size);
|
||||
pos.setX((screen.width()-size.width())/2);
|
||||
pos.setY((screen.height()-size.height())/2);
|
||||
}
|
||||
@@ -923,11 +983,17 @@ void TrianglesGUI::closeEvent(QCloseEvent *event)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Actually closing - quit the application
|
||||
QApplication::quit();
|
||||
// Actually closing - request a full core shutdown before leaving the UI loop.
|
||||
StartShutdown();
|
||||
event->accept();
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void TrianglesGUI::requestShutdown()
|
||||
{
|
||||
StartShutdown();
|
||||
}
|
||||
|
||||
void TrianglesGUI::askFee(qint64 nFeeRequired, bool *payFee)
|
||||
{
|
||||
QString strMessage = tr("<font color='#f26522'>This transaction is over the size limit. You can still send it for a fee of %1, "
|
||||
@@ -1070,6 +1136,8 @@ void TrianglesGUI::gotoReceiveCoinsPage()
|
||||
|
||||
void TrianglesGUI::gotoSendCoinsPage()
|
||||
{
|
||||
ensureSendCoinsPage();
|
||||
|
||||
sendCoinsAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(sendCoinsPage);
|
||||
|
||||
@@ -1079,6 +1147,7 @@ void TrianglesGUI::gotoSendCoinsPage()
|
||||
|
||||
void TrianglesGUI::gotoMessagePage()
|
||||
{
|
||||
ensureMessagePage();
|
||||
ensureMessageModel();
|
||||
|
||||
messageAction->setChecked(true);
|
||||
@@ -1091,6 +1160,8 @@ void TrianglesGUI::gotoMessagePage()
|
||||
|
||||
void TrianglesGUI::gotoSignMessageTab(QString addr)
|
||||
{
|
||||
ensureSignMessagePage();
|
||||
|
||||
centralWidget->setCurrentWidget(signMessagePage);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
@@ -1105,6 +1176,8 @@ void TrianglesGUI::gotoSignMessageTab(QString addr)
|
||||
|
||||
void TrianglesGUI::gotoVerifyMessageTab(QString addr)
|
||||
{
|
||||
ensureVerifyMessagePage();
|
||||
|
||||
centralWidget->setCurrentWidget(verifyMessagePage);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
@@ -1128,6 +1201,7 @@ void TrianglesGUI::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if(event->mimeData()->hasUrls())
|
||||
{
|
||||
ensureSendCoinsPage();
|
||||
int nValidUrisFound = 0;
|
||||
QList<QUrl> uris = event->mimeData()->urls();
|
||||
foreach(const QUrl &uri, uris)
|
||||
@@ -1209,6 +1283,7 @@ void TrianglesGUI::updateMask()
|
||||
void TrianglesGUI::handleURI(QString strURI)
|
||||
{
|
||||
// URI has to be valid
|
||||
ensureSendCoinsPage();
|
||||
if (sendCoinsPage->handleURI(strURI))
|
||||
{
|
||||
showNormalIfMinimized();
|
||||
@@ -1265,6 +1340,12 @@ void TrianglesGUI::menuFileRequested()
|
||||
}
|
||||
}
|
||||
|
||||
void TrianglesGUI::openRPCConsole()
|
||||
{
|
||||
ensureRPCConsole();
|
||||
rpcConsole->show();
|
||||
}
|
||||
|
||||
void TrianglesGUI::menuOperationsRequested()
|
||||
{
|
||||
QMenu menu(this);
|
||||
@@ -1564,5 +1645,6 @@ void TrianglesGUI::detectShutdown()
|
||||
|
||||
void TrianglesGUI::on_bHelp_clicked()
|
||||
{
|
||||
ensureRPCConsole();
|
||||
rpcConsole->show();
|
||||
}
|
||||
|
||||
@@ -79,6 +79,11 @@ protected:
|
||||
|
||||
private:
|
||||
void updateMask();
|
||||
void ensureSendCoinsPage();
|
||||
void ensureMessagePage();
|
||||
void ensureSignMessagePage();
|
||||
void ensureVerifyMessagePage();
|
||||
void ensureRPCConsole();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
@@ -181,6 +186,8 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void ensureMessageModel();
|
||||
void openRPCConsole();
|
||||
void requestShutdown();
|
||||
|
||||
void menuFileRequested();
|
||||
void menuOperationsRequested();
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
VerifyMessagePage::VerifyMessagePage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::VerifyMessagePage),
|
||||
|
||||
@@ -168,7 +168,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||
std::vector<COutput> vCoins;
|
||||
wallet->AvailableCoins(vCoins, true, coinControl);
|
||||
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
for (const COutput& out : vCoins)
|
||||
nBalance += out.tx->vout[out.i].nValue;
|
||||
|
||||
if(total > nBalance)
|
||||
@@ -451,7 +451,7 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||
// returns a list of COutputs from COutPoints
|
||||
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
|
||||
{
|
||||
BOOST_FOREACH(const COutPoint& outpoint, vOutpoints)
|
||||
for (const COutPoint& outpoint : vOutpoints)
|
||||
{
|
||||
if (!wallet->mapWallet.count(outpoint.hash)) continue;
|
||||
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
|
||||
@@ -469,7 +469,7 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
|
||||
std::vector<COutPoint> vLockedCoins;
|
||||
|
||||
// add locked coins
|
||||
BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins)
|
||||
for (const COutPoint& outpoint : vLockedCoins)
|
||||
{
|
||||
if (!wallet->mapWallet.count(outpoint.hash)) continue;
|
||||
int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
|
||||
@@ -478,7 +478,7 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
|
||||
vCoins.push_back(out);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
for (const COutput& out : vCoins)
|
||||
{
|
||||
COutput cout = out;
|
||||
|
||||
|
||||
+1
-2
@@ -13,7 +13,6 @@
|
||||
#include "init.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
@@ -393,7 +392,7 @@ static bool HandleMempool(string& strReply, int& nStatus)
|
||||
vector<uint256> vtxid;
|
||||
mempool.queryHashes(vtxid);
|
||||
Array a;
|
||||
BOOST_FOREACH(const uint256& hash, vtxid)
|
||||
for (const uint256& hash : vtxid)
|
||||
a.push_back(hash.ToString());
|
||||
strReply = write_string(Value(a), false) + "\n";
|
||||
nStatus = HTTP_OK;
|
||||
|
||||
@@ -128,7 +128,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPri
|
||||
result.push_back(Pair("modifier", strprintf("%016"PRIx64, blockindex->nStakeModifier)));
|
||||
result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
|
||||
Array txinfo;
|
||||
BOOST_FOREACH (const CTransaction& tx, block.vtx)
|
||||
for (const CTransaction& tx : block.vtx)
|
||||
{
|
||||
if (fPrintTransactionDetail)
|
||||
{
|
||||
@@ -211,7 +211,7 @@ Value getrawmempool(const Array& params, bool fHelp)
|
||||
mempool.queryHashes(vtxid);
|
||||
|
||||
Array a;
|
||||
BOOST_FOREACH(const uint256& hash, vtxid)
|
||||
for (const uint256& hash : vtxid)
|
||||
a.push_back(hash.ToString());
|
||||
|
||||
return a;
|
||||
@@ -431,13 +431,13 @@ static bool ParseAddress(const std::string& strAddr, int& nType, uint160& hashBy
|
||||
return false;
|
||||
|
||||
CTxDestination dest = addr.Get();
|
||||
const CKeyID* keyId = boost::get<CKeyID>(&dest);
|
||||
const CKeyID* keyId = std::get_if<CKeyID>(&dest);
|
||||
if (keyId) {
|
||||
nType = ADDR_TYPE_P2PKH;
|
||||
hashBytes = *keyId;
|
||||
return true;
|
||||
}
|
||||
const CScriptID* scriptId = boost::get<CScriptID>(&dest);
|
||||
const CScriptID* scriptId = std::get_if<CScriptID>(&dest);
|
||||
if (scriptId) {
|
||||
nType = ADDR_TYPE_P2SH;
|
||||
hashBytes = *scriptId;
|
||||
|
||||
+1
-2
@@ -11,7 +11,6 @@
|
||||
#include "base58.h"
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/variant/get.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#define printf OutputDebugStringF
|
||||
@@ -63,7 +62,7 @@ std::string static EncodeDumpTime(int64_t nTime) {
|
||||
|
||||
std::string static EncodeDumpString(const std::string &str) {
|
||||
std::stringstream ret;
|
||||
BOOST_FOREACH(unsigned char c, str) {
|
||||
for (unsigned char c : str) {
|
||||
if (c <= 32 || c >= 128 || c == '%') {
|
||||
ret << '%' << HexStr(&c, &c + 1);
|
||||
} else {
|
||||
|
||||
+5
-5
@@ -144,7 +144,7 @@ Value getworkex(const Array& params, bool fHelp)
|
||||
{
|
||||
// Deallocate old blocks since they're obsolete now
|
||||
mapNewBlock.clear();
|
||||
BOOST_FOREACH(CBlock* pblock, vNewBlock)
|
||||
for (CBlock* pblock : vNewBlock)
|
||||
delete pblock;
|
||||
vNewBlock.clear();
|
||||
}
|
||||
@@ -191,7 +191,7 @@ Value getworkex(const Array& params, bool fHelp)
|
||||
|
||||
Array merkle_arr;
|
||||
|
||||
BOOST_FOREACH(uint256 merkleh, merkle) {
|
||||
for (uint256 merkleh : merkle) {
|
||||
merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh)));
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ Value getwork(const Array& params, bool fHelp)
|
||||
{
|
||||
// Deallocate old blocks since they're obsolete now
|
||||
mapNewBlock.clear();
|
||||
BOOST_FOREACH(CBlock* pblock, vNewBlock)
|
||||
for (CBlock* pblock : vNewBlock)
|
||||
delete pblock;
|
||||
vNewBlock.clear();
|
||||
}
|
||||
@@ -442,7 +442,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
||||
map<uint256, int64_t> setTxIndex;
|
||||
int i = 0;
|
||||
CTxDB txdb("r");
|
||||
BOOST_FOREACH (CTransaction& tx, pblock->vtx)
|
||||
for (CTransaction& tx : pblock->vtx)
|
||||
{
|
||||
uint256 txHash = tx.GetHash();
|
||||
setTxIndex[txHash] = i++;
|
||||
@@ -466,7 +466,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
||||
entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut())));
|
||||
|
||||
Array deps;
|
||||
BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs)
|
||||
for (MapPrevTx::value_type& inp : mapInputs)
|
||||
{
|
||||
if (setTxIndex.count(inp.first))
|
||||
deps.push_back(setTxIndex[inp.first]);
|
||||
|
||||
+3
-3
@@ -51,7 +51,7 @@ static void CopyNodeStats(std::vector<CNodeStats>& vstats)
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
vstats.reserve(vNodes.size());
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
for (CNode* pnode : vNodes) {
|
||||
CNodeStats stats;
|
||||
pnode->copyStats(stats);
|
||||
vstats.push_back(stats);
|
||||
@@ -70,7 +70,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
||||
|
||||
Array ret;
|
||||
|
||||
BOOST_FOREACH(const CNodeStats& stats, vstats) {
|
||||
for (const CNodeStats& stats : vstats) {
|
||||
Object obj;
|
||||
|
||||
obj.push_back(Pair("addr", stats.addrName));
|
||||
@@ -140,7 +140,7 @@ Value sendalert(const Array& params, bool fHelp)
|
||||
// Relay alert
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
alert.RelayTo(pnode);
|
||||
}
|
||||
|
||||
|
||||
+25
-29
@@ -3,8 +3,6 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include "base58.h"
|
||||
#include "trianglesrpc.h"
|
||||
#include "txdb.h"
|
||||
@@ -15,7 +13,6 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace boost::assign;
|
||||
using namespace json_spirit;
|
||||
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
|
||||
@@ -39,7 +36,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH
|
||||
out.push_back(Pair("type", GetTxnOutputType(type)));
|
||||
|
||||
Array a;
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
for (const CTxDestination& addr : addresses)
|
||||
a.push_back(CTrianglesAddress(addr).ToString());
|
||||
out.push_back(Pair("addresses", a));
|
||||
}
|
||||
@@ -51,7 +48,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
entry.push_back(Pair("time", (boost::int64_t)tx.nTime));
|
||||
entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime));
|
||||
Array vin;
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
Object in;
|
||||
if (tx.IsCoinBase())
|
||||
@@ -148,7 +145,7 @@ Value listunspent(const Array& params, bool fHelp)
|
||||
"Results are an array of Objects, each of which has:\n"
|
||||
"{txid, vout, scriptPubKey, amount, confirmations}");
|
||||
|
||||
RPCTypeCheck(params, list_of(int_type)(int_type)(array_type));
|
||||
RPCTypeCheck(params, {int_type, int_type, array_type});
|
||||
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 0)
|
||||
@@ -162,7 +159,7 @@ Value listunspent(const Array& params, bool fHelp)
|
||||
if (params.size() > 2)
|
||||
{
|
||||
Array inputs = params[2].get_array();
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
for (Value& input : inputs)
|
||||
{
|
||||
CTrianglesAddress address(input.get_str());
|
||||
if (!address.IsValid())
|
||||
@@ -176,7 +173,7 @@ Value listunspent(const Array& params, bool fHelp)
|
||||
Array results;
|
||||
vector<COutput> vecOutputs;
|
||||
pwalletMain->AvailableCoins(vecOutputs, false);
|
||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||
for (const COutput& out : vecOutputs)
|
||||
{
|
||||
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
|
||||
continue;
|
||||
@@ -224,14 +221,14 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
||||
"Note that the transaction's inputs are not signed, and\n"
|
||||
"it is not stored in the wallet or transmitted to the network.");
|
||||
|
||||
RPCTypeCheck(params, list_of(array_type)(obj_type));
|
||||
RPCTypeCheck(params, {array_type, obj_type});
|
||||
|
||||
Array inputs = params[0].get_array();
|
||||
Object sendTo = params[1].get_obj();
|
||||
|
||||
CTransaction rawTx;
|
||||
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
for (Value& input : inputs)
|
||||
{
|
||||
const Object& o = input.get_obj();
|
||||
|
||||
@@ -254,7 +251,7 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
||||
}
|
||||
|
||||
set<CTrianglesAddress> setAddress;
|
||||
BOOST_FOREACH(const Pair& s, sendTo)
|
||||
for (const Pair& s : sendTo)
|
||||
{
|
||||
CTrianglesAddress address(s.name_);
|
||||
if (!address.IsValid())
|
||||
@@ -284,7 +281,7 @@ Value decoderawtransaction(const Array& params, bool fHelp)
|
||||
"decoderawtransaction <hex string>\n"
|
||||
"Return a JSON object representing the serialized, hex-encoded transaction.");
|
||||
|
||||
RPCTypeCheck(params, list_of(str_type));
|
||||
RPCTypeCheck(params, {str_type});
|
||||
|
||||
vector<unsigned char> txData(ParseHex(params[0].get_str()));
|
||||
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -309,7 +306,7 @@ Value decodescript(const Array& params, bool fHelp)
|
||||
"decodescript <hex string>\n"
|
||||
"Decode a hex-encoded script.");
|
||||
|
||||
RPCTypeCheck(params, list_of(str_type));
|
||||
RPCTypeCheck(params, {str_type});
|
||||
|
||||
Object r;
|
||||
CScript script;
|
||||
@@ -342,7 +339,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
" complete : 1 if transaction has a complete set of signature (0 if not)"
|
||||
+ HelpRequiringPassphrase());
|
||||
|
||||
RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true);
|
||||
RPCTypeCheck(params, {str_type, array_type, array_type, str_type}, true);
|
||||
|
||||
vector<unsigned char> txData(ParseHex(params[0].get_str()));
|
||||
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -382,7 +379,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
tempTx.FetchInputs(txdb, unused, false, false, mapPrevTx, fInvalid);
|
||||
|
||||
// Copy results into mapPrevOut:
|
||||
BOOST_FOREACH(const CTxIn& txin, tempTx.vin)
|
||||
for (const CTxIn& txin : tempTx.vin)
|
||||
{
|
||||
const uint256& prevHash = txin.prevout.hash;
|
||||
if (mapPrevTx.count(prevHash) && mapPrevTx[prevHash].second.vout.size()>txin.prevout.n)
|
||||
@@ -394,14 +391,14 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
if (params.size() > 1 && params[1].type() != null_type)
|
||||
{
|
||||
Array prevTxs = params[1].get_array();
|
||||
BOOST_FOREACH(Value& p, prevTxs)
|
||||
for (Value& p : prevTxs)
|
||||
{
|
||||
if (p.type() != obj_type)
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
|
||||
|
||||
Object prevOut = p.get_obj();
|
||||
|
||||
RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
|
||||
RPCTypeCheck(prevOut, {{"txid", str_type}, {"vout", int_type}, {"scriptPubKey", str_type}});
|
||||
|
||||
string txidHex = find_value(prevOut, "txid").get_str();
|
||||
if (!IsHex(txidHex))
|
||||
@@ -442,7 +439,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
{
|
||||
fGivenKeys = true;
|
||||
Array keys = params[2].get_array();
|
||||
BOOST_FOREACH(Value k, keys)
|
||||
for (Value k : keys)
|
||||
{
|
||||
CTrianglesSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(k.get_str());
|
||||
@@ -463,15 +460,14 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
int nHashType = SIGHASH_ALL;
|
||||
if (params.size() > 3 && params[3].type() != null_type)
|
||||
{
|
||||
static map<string, int> mapSigHashValues =
|
||||
boost::assign::map_list_of
|
||||
(string("ALL"), int(SIGHASH_ALL))
|
||||
(string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
|
||||
(string("NONE"), int(SIGHASH_NONE))
|
||||
(string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
|
||||
(string("SINGLE"), int(SIGHASH_SINGLE))
|
||||
(string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
|
||||
;
|
||||
static map<string, int> mapSigHashValues = {
|
||||
{"ALL", int(SIGHASH_ALL)},
|
||||
{"ALL|ANYONECANPAY", int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
|
||||
{"NONE", int(SIGHASH_NONE)},
|
||||
{"NONE|ANYONECANPAY", int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
|
||||
{"SINGLE", int(SIGHASH_SINGLE)},
|
||||
{"SINGLE|ANYONECANPAY", int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
|
||||
};
|
||||
string strHashType = params[3].get_str();
|
||||
if (mapSigHashValues.count(strHashType))
|
||||
nHashType = mapSigHashValues[strHashType];
|
||||
@@ -498,7 +494,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||
SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
|
||||
|
||||
// ... and merge in other signatures:
|
||||
BOOST_FOREACH(const CTransaction& txv, txVariants)
|
||||
for (const CTransaction& txv : txVariants)
|
||||
{
|
||||
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
|
||||
}
|
||||
@@ -522,7 +518,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||
"sendrawtransaction <hex string>\n"
|
||||
"Submits raw transaction (serialized, hex-encoded) to local node and network.");
|
||||
|
||||
RPCTypeCheck(params, list_of(str_type));
|
||||
RPCTypeCheck(params, {str_type});
|
||||
|
||||
// parse hex string from parameter
|
||||
vector<unsigned char> txData(ParseHex(params[0].get_str()));
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@
|
||||
#include "main.h"
|
||||
#include "trianglesrpc.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "smessage.h"
|
||||
#include "init.h" // pwalletMain
|
||||
@@ -301,7 +301,7 @@ Value smsglocalkeys(const Array& params, bool fHelp)
|
||||
if (mode == "wallet")
|
||||
{
|
||||
uint32_t nKeys = 0;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& entry, pwalletMain->mapAddressBook)
|
||||
for (const auto& entry : pwalletMain->mapAddressBook)
|
||||
{
|
||||
if (!IsMine(*pwalletMain, entry.first))
|
||||
continue;
|
||||
@@ -802,13 +802,13 @@ Value smsgbuckets(const Array& params, bool fHelp)
|
||||
{
|
||||
std::set<SecMsgToken>& tokenSet = it->second.setTokens;
|
||||
|
||||
std::string sBucket = boost::lexical_cast<std::string>(it->first);
|
||||
std::string sBucket = std::to_string(it->first);
|
||||
std::string sFile = sBucket + "_01.dat";
|
||||
|
||||
snprintf(cbuf, sizeof(cbuf), "%"PRIszu, tokenSet.size());
|
||||
std::string snContents(cbuf);
|
||||
|
||||
std::string sHash = boost::lexical_cast<std::string>(it->second.hash);
|
||||
std::string sHash = std::to_string(it->second.hash);
|
||||
|
||||
nBuckets++;
|
||||
nMessages += tokenSet.size();
|
||||
@@ -849,8 +849,8 @@ Value smsgbuckets(const Array& params, bool fHelp)
|
||||
}; // LOCK(cs_smsg);
|
||||
|
||||
|
||||
std::string snBuckets = boost::lexical_cast<std::string>(nBuckets);
|
||||
std::string snMessages = boost::lexical_cast<std::string>(nMessages);
|
||||
std::string snBuckets = std::to_string(nBuckets);
|
||||
std::string snMessages = std::to_string(nMessages);
|
||||
|
||||
Object objM;
|
||||
objM.push_back(Pair("buckets", snBuckets));
|
||||
@@ -868,7 +868,7 @@ Value smsgbuckets(const Array& params, bool fHelp)
|
||||
|
||||
for (it = smsgBuckets.begin(); it != smsgBuckets.end(); ++it)
|
||||
{
|
||||
std::string sFile = boost::lexical_cast<std::string>(it->first) + "_01.dat";
|
||||
std::string sFile = std::to_string(it->first) + "_01.dat";
|
||||
|
||||
try {
|
||||
boost::filesystem::path fullPath = GetDataDir() / "smsgStore" / sFile;
|
||||
|
||||
+24
-24
@@ -60,7 +60,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
|
||||
entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
|
||||
entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
|
||||
entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived));
|
||||
BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
|
||||
for (const auto& item : wtx.mapValue)
|
||||
entry.push_back(Pair(item.first, item.second));
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ CTrianglesAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||
++it)
|
||||
{
|
||||
const CWalletTx& wtx = (*it).second;
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
if (txout.scriptPubKey == scriptPubKey)
|
||||
bKeyUsed = true;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
|
||||
|
||||
// Find all addresses that have the given account
|
||||
Array ret;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTrianglesAddress, string)& item, pwalletMain->mapAddressBook)
|
||||
for (const auto& item : pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CTrianglesAddress& address = item.first;
|
||||
const string& strName = item.second;
|
||||
@@ -366,10 +366,10 @@ Value listaddressgroupings(const Array& params, bool fHelp)
|
||||
|
||||
Array jsonGroupings;
|
||||
map<CTxDestination, int64_t> balances = pwalletMain->GetAddressBalances();
|
||||
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
|
||||
for (set<CTxDestination> grouping : pwalletMain->GetAddressGroupings())
|
||||
{
|
||||
Array jsonGrouping;
|
||||
BOOST_FOREACH(CTxDestination address, grouping)
|
||||
for (CTxDestination address : grouping)
|
||||
{
|
||||
Array addressInfo;
|
||||
addressInfo.push_back(CTrianglesAddress(address).ToString());
|
||||
@@ -487,7 +487,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
||||
if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal())
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
if (txout.scriptPubKey == scriptPubKey)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
@@ -499,7 +499,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
||||
|
||||
void GetAccountAddresses(string strAccount, set<CTxDestination>& setAddress)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& item, pwalletMain->mapAddressBook)
|
||||
for (const auto& item : pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CTxDestination& address = item.first;
|
||||
const string& strName = item.second;
|
||||
@@ -535,7 +535,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
|
||||
if (wtx.IsCoinBase() || wtx.IsCoinStake() || !wtx.IsFinal())
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
{
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address))
|
||||
@@ -613,10 +613,10 @@ Value getbalance(const Array& params, bool fHelp)
|
||||
wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount);
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
|
||||
for (const auto& r : listReceived)
|
||||
nBalance += r.second;
|
||||
}
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listSent)
|
||||
for (const auto& r : listSent)
|
||||
nBalance -= r.second;
|
||||
nBalance -= allFee;
|
||||
}
|
||||
@@ -754,7 +754,7 @@ Value sendmany(const Array& params, bool fHelp)
|
||||
vector<pair<CScript, int64_t> > vecSend;
|
||||
|
||||
int64_t totalAmount = 0;
|
||||
BOOST_FOREACH(const Pair& s, sendTo)
|
||||
for (const Pair& s : sendTo)
|
||||
{
|
||||
CTrianglesAddress address(s.name_);
|
||||
if (!address.IsValid())
|
||||
@@ -925,7 +925,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
||||
if (nDepth < nMinDepth)
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
|
||||
for (const CTxOut& txout : wtx.vout)
|
||||
{
|
||||
CTxDestination address;
|
||||
if (!ExtractDestination(txout.scriptPubKey, address) || !IsMine(*pwalletMain, address))
|
||||
@@ -940,7 +940,7 @@ Value ListReceived(const Array& params, bool fByAccounts)
|
||||
// Reply
|
||||
Array ret;
|
||||
map<string, tallyitem> mapAccountTally;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTrianglesAddress, string)& item, pwalletMain->mapAddressBook)
|
||||
for (const auto& item : pwalletMain->mapAddressBook)
|
||||
{
|
||||
const CTrianglesAddress& address = item.first;
|
||||
const string& strAccount = item.second;
|
||||
@@ -1044,7 +1044,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||
// Sent
|
||||
if ((!wtx.IsCoinStake()) && (!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
|
||||
for (const auto& s : listSent)
|
||||
{
|
||||
Object entry;
|
||||
entry.push_back(Pair("account", strSentAccount));
|
||||
@@ -1062,7 +1062,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
{
|
||||
bool stop = false;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
|
||||
for (const auto& r : listReceived)
|
||||
{
|
||||
string account;
|
||||
if (pwalletMain->mapAddressBook.count(r.first))
|
||||
@@ -1191,7 +1191,7 @@ Value listaccounts(const Array& params, bool fHelp)
|
||||
nMinDepth = params[0].get_int();
|
||||
|
||||
map<string, int64_t> mapAccountBalances;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, string)& entry, pwalletMain->mapAddressBook) {
|
||||
for (const auto& entry : pwalletMain->mapAddressBook) {
|
||||
if (IsMine(*pwalletMain, entry.first)) // This address belongs to me
|
||||
mapAccountBalances[entry.second] = 0;
|
||||
}
|
||||
@@ -1208,11 +1208,11 @@ Value listaccounts(const Array& params, bool fHelp)
|
||||
continue;
|
||||
wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount);
|
||||
mapAccountBalances[strSentAccount] -= nFee;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& s, listSent)
|
||||
for (const auto& s : listSent)
|
||||
mapAccountBalances[strSentAccount] -= s.second;
|
||||
if (nDepth >= nMinDepth && wtx.GetBlocksToMaturity() == 0)
|
||||
{
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64_t)& r, listReceived)
|
||||
for (const auto& r : listReceived)
|
||||
if (pwalletMain->mapAddressBook.count(r.first))
|
||||
mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
|
||||
else
|
||||
@@ -1222,11 +1222,11 @@ Value listaccounts(const Array& params, bool fHelp)
|
||||
|
||||
list<CAccountingEntry> acentries;
|
||||
CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
|
||||
BOOST_FOREACH(const CAccountingEntry& entry, acentries)
|
||||
for (const CAccountingEntry& entry : acentries)
|
||||
mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
|
||||
|
||||
Object ret;
|
||||
BOOST_FOREACH(const PAIRTYPE(string, int64_t)& accountBalance, mapAccountBalances) {
|
||||
for (const auto& accountBalance : mapAccountBalances) {
|
||||
ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
|
||||
}
|
||||
return ret;
|
||||
@@ -1587,7 +1587,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||
return "wallet encrypted; Triangles server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
|
||||
}
|
||||
|
||||
class DescribeAddressVisitor : public boost::static_visitor<Object>
|
||||
class DescribeAddressVisitor
|
||||
{
|
||||
public:
|
||||
Object operator()(const CNoDestination &dest) const { return Object(); }
|
||||
@@ -1614,7 +1614,7 @@ public:
|
||||
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
|
||||
obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
|
||||
Array a;
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
for (const CTxDestination& addr : addresses)
|
||||
a.push_back(CTrianglesAddress(addr).ToString());
|
||||
obj.push_back(Pair("addresses", a));
|
||||
if (whichType == TX_MULTISIG)
|
||||
@@ -1644,7 +1644,7 @@ Value validateaddress(const Array& params, bool fHelp)
|
||||
bool fMine = IsMine(*pwalletMain, dest);
|
||||
ret.push_back(Pair("ismine", fMine));
|
||||
if (fMine) {
|
||||
Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
Object detail = std::visit(DescribeAddressVisitor(), dest);
|
||||
ret.insert(ret.end(), detail.begin(), detail.end());
|
||||
}
|
||||
if (pwalletMain->mapAddressBook.count(dest))
|
||||
@@ -1681,7 +1681,7 @@ Value validatepubkey(const Array& params, bool fHelp)
|
||||
ret.push_back(Pair("ismine", fMine));
|
||||
ret.push_back(Pair("iscompressed", isCompressed));
|
||||
if (fMine) {
|
||||
Object detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
Object detail = std::visit(DescribeAddressVisitor(), dest);
|
||||
ret.insert(ret.end(), detail.begin(), detail.end());
|
||||
}
|
||||
if (pwalletMain->mapAddressBook.count(dest))
|
||||
|
||||
+16
-19
@@ -3,12 +3,9 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
#include "script.h"
|
||||
#include "keystore.h"
|
||||
@@ -1214,7 +1211,7 @@ class CSignatureCache
|
||||
{
|
||||
private:
|
||||
// sigdata_type is (signature hash, signature, public key):
|
||||
typedef boost::tuple<uint256, std::vector<unsigned char>, std::vector<unsigned char> > sigdata_type;
|
||||
typedef std::tuple<uint256, std::vector<unsigned char>, std::vector<unsigned char> > sigdata_type;
|
||||
std::set< sigdata_type> setValid;
|
||||
CCriticalSection cs_sigcache;
|
||||
|
||||
@@ -1331,7 +1328,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
||||
|
||||
// Scan templates
|
||||
const CScript& script1 = scriptPubKey;
|
||||
BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
|
||||
for (const auto& tplate : mTemplates)
|
||||
{
|
||||
const CScript& script2 = tplate.second;
|
||||
vSolutionsRet.clear();
|
||||
@@ -1533,7 +1530,7 @@ bool IsStandard(const CScript& scriptPubKey)
|
||||
unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
|
||||
{
|
||||
unsigned int nResult = 0;
|
||||
BOOST_FOREACH(const valtype& pubkey, pubkeys)
|
||||
for (const valtype& pubkey : pubkeys)
|
||||
{
|
||||
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||
if (keystore.HaveKey(keyID))
|
||||
@@ -1543,7 +1540,7 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
|
||||
}
|
||||
|
||||
|
||||
class CKeyStoreIsMineVisitor : public boost::static_visitor<bool>
|
||||
class CKeyStoreIsMineVisitor
|
||||
{
|
||||
private:
|
||||
const CKeyStore *keystore;
|
||||
@@ -1556,7 +1553,7 @@ public:
|
||||
|
||||
bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
|
||||
{
|
||||
return boost::apply_visitor(CKeyStoreIsMineVisitor(&keystore), dest);
|
||||
return std::visit(CKeyStoreIsMineVisitor(&keystore), dest);
|
||||
}
|
||||
|
||||
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
@@ -1624,7 +1621,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
return false;
|
||||
}
|
||||
|
||||
class CAffectedKeysVisitor : public boost::static_visitor<void> {
|
||||
class CAffectedKeysVisitor {
|
||||
private:
|
||||
const CKeyStore &keystore;
|
||||
std::vector<CKeyID> &vKeys;
|
||||
@@ -1637,8 +1634,8 @@ public:
|
||||
std::vector<CTxDestination> vDest;
|
||||
int nRequired;
|
||||
if (ExtractDestinations(script, type, vDest, nRequired)) {
|
||||
BOOST_FOREACH(const CTxDestination &dest, vDest)
|
||||
boost::apply_visitor(*this, dest);
|
||||
for (const CTxDestination &dest : vDest)
|
||||
std::visit(*this, dest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1792,7 +1789,7 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
|
||||
static CScript PushAll(const vector<valtype>& values)
|
||||
{
|
||||
CScript result;
|
||||
BOOST_FOREACH(const valtype& v, values)
|
||||
for (const valtype& v : values)
|
||||
result << v;
|
||||
return result;
|
||||
}
|
||||
@@ -1803,12 +1800,12 @@ static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, u
|
||||
{
|
||||
// Combine all the signatures we've got:
|
||||
set<valtype> allsigs;
|
||||
BOOST_FOREACH(const valtype& v, sigs1)
|
||||
for (const valtype& v : sigs1)
|
||||
{
|
||||
if (!v.empty())
|
||||
allsigs.insert(v);
|
||||
}
|
||||
BOOST_FOREACH(const valtype& v, sigs2)
|
||||
for (const valtype& v : sigs2)
|
||||
{
|
||||
if (!v.empty())
|
||||
allsigs.insert(v);
|
||||
@@ -1819,7 +1816,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, u
|
||||
unsigned int nSigsRequired = vSolutions.front()[0];
|
||||
unsigned int nPubKeys = vSolutions.size()-2;
|
||||
map<valtype, valtype> sigs;
|
||||
BOOST_FOREACH(const valtype& sig, allsigs)
|
||||
for (const valtype& sig : allsigs)
|
||||
{
|
||||
for (unsigned int i = 0; i < nPubKeys; i++)
|
||||
{
|
||||
@@ -1995,7 +1992,7 @@ bool CScript::HasCanonicalPushes() const
|
||||
return true;
|
||||
}
|
||||
|
||||
class CScriptVisitor : public boost::static_visitor<bool>
|
||||
class CScriptVisitor
|
||||
{
|
||||
private:
|
||||
CScript *script;
|
||||
@@ -2023,7 +2020,7 @@ public:
|
||||
|
||||
void CScript::SetDestination(const CTxDestination& dest)
|
||||
{
|
||||
boost::apply_visitor(CScriptVisitor(this), dest);
|
||||
std::visit(CScriptVisitor(this), dest);
|
||||
}
|
||||
|
||||
void CScript::SetMultisig(int nRequired, const std::vector<CKey>& keys)
|
||||
@@ -2031,7 +2028,7 @@ void CScript::SetMultisig(int nRequired, const std::vector<CKey>& keys)
|
||||
this->clear();
|
||||
|
||||
*this << EncodeOP_N(nRequired);
|
||||
BOOST_FOREACH(const CKey& key, keys)
|
||||
for (const CKey& key : keys)
|
||||
*this << key.GetPubKey();
|
||||
*this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
|
||||
}
|
||||
|
||||
+3
-4
@@ -11,8 +11,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <variant>
|
||||
|
||||
#include "keystore.h"
|
||||
#include "bignum.h"
|
||||
@@ -53,7 +52,7 @@ public:
|
||||
* * CScriptID: TX_SCRIPTHASH destination
|
||||
* A CTxDestination is the internal data type encoded in a CTrianglesAddress
|
||||
*/
|
||||
typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
||||
typedef std::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
||||
|
||||
const char* GetTxnOutputType(txnouttype t);
|
||||
|
||||
@@ -218,7 +217,7 @@ inline std::string ValueString(const std::vector<unsigned char>& vch)
|
||||
inline std::string StackString(const std::vector<std::vector<unsigned char> >& vStack)
|
||||
{
|
||||
std::string str;
|
||||
BOOST_FOREACH(const std::vector<unsigned char>& vch, vStack)
|
||||
for (const std::vector<unsigned char>& vch : vStack)
|
||||
{
|
||||
if (!str.empty())
|
||||
str += " ";
|
||||
|
||||
+34
-36
@@ -17,9 +17,7 @@
|
||||
#include <cstdio>
|
||||
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <boost/tuple/tuple_io.hpp>
|
||||
#include <tuple>
|
||||
|
||||
#include "allocators.h"
|
||||
#include "version.h"
|
||||
@@ -310,14 +308,14 @@ template<typename Stream, typename K, typename T> void Serialize(Stream& os, con
|
||||
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
|
||||
|
||||
// 3 tuple
|
||||
template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const std::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const std::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, std::tuple<T0, T1, T2>& item, int nType, int nVersion);
|
||||
|
||||
// 4 tuple
|
||||
template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
|
||||
|
||||
// map
|
||||
template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
|
||||
@@ -530,29 +528,29 @@ void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
|
||||
// 3 tuple
|
||||
//
|
||||
template<typename T0, typename T1, typename T2>
|
||||
unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
unsigned int GetSerializeSize(const std::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<2>(item), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2>
|
||||
void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
void Serialize(Stream& os, const std::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
Serialize(os, boost::get<0>(item), nType, nVersion);
|
||||
Serialize(os, boost::get<1>(item), nType, nVersion);
|
||||
Serialize(os, boost::get<2>(item), nType, nVersion);
|
||||
Serialize(os, std::get<0>(item), nType, nVersion);
|
||||
Serialize(os, std::get<1>(item), nType, nVersion);
|
||||
Serialize(os, std::get<2>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2>
|
||||
void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
void Unserialize(Stream& is, std::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
Unserialize(is, boost::get<0>(item), nType, nVersion);
|
||||
Unserialize(is, boost::get<1>(item), nType, nVersion);
|
||||
Unserialize(is, boost::get<2>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<0>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<1>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<2>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
@@ -561,32 +559,32 @@ void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVer
|
||||
// 4 tuple
|
||||
//
|
||||
template<typename T0, typename T1, typename T2, typename T3>
|
||||
unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
unsigned int GetSerializeSize(const std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<2>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(std::get<3>(item), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3>
|
||||
void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
void Serialize(Stream& os, const std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
Serialize(os, boost::get<0>(item), nType, nVersion);
|
||||
Serialize(os, boost::get<1>(item), nType, nVersion);
|
||||
Serialize(os, boost::get<2>(item), nType, nVersion);
|
||||
Serialize(os, boost::get<3>(item), nType, nVersion);
|
||||
Serialize(os, std::get<0>(item), nType, nVersion);
|
||||
Serialize(os, std::get<1>(item), nType, nVersion);
|
||||
Serialize(os, std::get<2>(item), nType, nVersion);
|
||||
Serialize(os, std::get<3>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3>
|
||||
void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
void Unserialize(Stream& is, std::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
Unserialize(is, boost::get<0>(item), nType, nVersion);
|
||||
Unserialize(is, boost::get<1>(item), nType, nVersion);
|
||||
Unserialize(is, boost::get<2>(item), nType, nVersion);
|
||||
Unserialize(is, boost::get<3>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<0>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<1>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<2>(item), nType, nVersion);
|
||||
Unserialize(is, std::get<3>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-17
@@ -44,7 +44,7 @@ Notes:
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <string>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Notes:
|
||||
#include "txdb.h"
|
||||
|
||||
|
||||
#include "lz4/lz4.c"
|
||||
#include "lz4/lz4.h"
|
||||
|
||||
#include "xxhash/xxhash.h"
|
||||
#include "xxhash/xxhash.c"
|
||||
@@ -627,7 +627,7 @@ void ThreadSecureMsg(void* parg)
|
||||
{
|
||||
if (fDebugSmsg)
|
||||
printf("Removing bucket %"PRId64" \n", it->first);
|
||||
std::string fileName = boost::lexical_cast<std::string>(it->first) + "_01.dat";
|
||||
std::string fileName = std::to_string(it->first) + "_01.dat";
|
||||
fs::path fullPath = GetDataDir() / "smsgStore" / fileName;
|
||||
if (fs::exists(fullPath))
|
||||
{
|
||||
@@ -641,7 +641,7 @@ void ThreadSecureMsg(void* parg)
|
||||
printf("Path %s does not exist \n", fullPath.string().c_str());
|
||||
|
||||
// -- look for a wl file, it stores incoming messages when wallet is locked
|
||||
fileName = boost::lexical_cast<std::string>(it->first) + "_01_wl.dat";
|
||||
fileName = std::to_string(it->first) + "_01_wl.dat";
|
||||
fullPath = GetDataDir() / "smsgStore" / fileName;
|
||||
if (fs::exists(fullPath))
|
||||
{
|
||||
@@ -670,7 +670,7 @@ void ThreadSecureMsg(void* parg)
|
||||
printf("Lock on bucket %"PRId64" for peer %u timed out.\n", it->first, nPeerId);
|
||||
// -- look through the nodes for the peer that locked this bucket
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (pnode->smsgData.nPeerId != nPeerId)
|
||||
continue;
|
||||
@@ -868,7 +868,7 @@ int SecureMsgBuildBucketSet()
|
||||
|
||||
std::string stime = fileName.substr(0, sep);
|
||||
|
||||
int64_t fileTime = boost::lexical_cast<int64_t>(stime);
|
||||
int64_t fileTime = std::stoll(stime);
|
||||
|
||||
if (fileTime < now - SMSG_RETENTION)
|
||||
{
|
||||
@@ -961,7 +961,7 @@ int SecureMsgAddWalletAddresses()
|
||||
printf("SecureMsgAddWalletAddresses()\n");
|
||||
|
||||
uint32_t nAdded = 0;
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& entry, pwalletMain->mapAddressBook)
|
||||
for (const auto& entry : pwalletMain->mapAddressBook)
|
||||
{
|
||||
if (!IsMine(*pwalletMain, entry.first))
|
||||
continue;
|
||||
@@ -1255,7 +1255,7 @@ bool SecureMsgEnable()
|
||||
// -- ping each peer, don't know which have messaging enabled
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
pnode->PushMessage("smsgPing");
|
||||
pnode->PushMessage("smsgPong"); // Send pong as have missed initial ping sent by peer when it connected
|
||||
@@ -1291,7 +1291,7 @@ bool SecureMsgDisable()
|
||||
// -- tell each smsg enabled peer that this node is disabling
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (!pnode->smsgData.fEnabled)
|
||||
continue;
|
||||
@@ -1947,7 +1947,7 @@ static bool ScanBlock(CBlock& block, CTxDB& txdb, SecMsgDB& addrpkdb,
|
||||
uint32_t& nTransactions, uint32_t& nInputs, uint32_t& nPubkeys, uint32_t& nDuplicates)
|
||||
{
|
||||
// -- should have LOCK(cs_smsg) where db is opened
|
||||
BOOST_FOREACH(CTransaction& tx, block.vtx)
|
||||
for (CTransaction& tx : block.vtx)
|
||||
{
|
||||
if (!tx.IsStandard())
|
||||
continue; // leave out coinbase and others
|
||||
@@ -2224,7 +2224,7 @@ bool SecureMsgScanBuckets()
|
||||
|
||||
std::string stime = fileName.substr(0, sep);
|
||||
|
||||
int64_t fileTime = boost::lexical_cast<int64_t>(stime);
|
||||
int64_t fileTime = std::stoll(stime);
|
||||
|
||||
if (fileTime < now - SMSG_RETENTION)
|
||||
{
|
||||
@@ -2378,7 +2378,7 @@ int SecureMsgWalletUnlocked()
|
||||
|
||||
std::string stime = fileName.substr(0, sep);
|
||||
|
||||
int64_t fileTime = boost::lexical_cast<int64_t>(stime);
|
||||
int64_t fileTime = std::stoll(stime);
|
||||
|
||||
if (fileTime < now - SMSG_RETENTION)
|
||||
{
|
||||
@@ -2769,7 +2769,7 @@ int SecureMsgRetrieve(SecMsgToken &token, std::vector<unsigned char>& vchData)
|
||||
|
||||
//printf("token.offset %"PRId64".\n", token.offset); // DEBUG
|
||||
int64_t bucket = token.timestamp - (token.timestamp % SMSG_BUCKET_LEN);
|
||||
std::string fileName = boost::lexical_cast<std::string>(bucket) + "_01.dat";
|
||||
std::string fileName = std::to_string(bucket) + "_01.dat";
|
||||
fs::path fullpath = pathSmsgDir / fileName;
|
||||
|
||||
//printf("bucket %"PRId64".\n", bucket);
|
||||
@@ -2972,7 +2972,7 @@ int SecureMsgStoreUnscanned(unsigned char *pHeader, unsigned char *pPayload, uin
|
||||
|
||||
int64_t bucket = psmsg->timestamp - (psmsg->timestamp % SMSG_BUCKET_LEN);
|
||||
|
||||
std::string fileName = boost::lexical_cast<std::string>(bucket) + "_01_wl.dat";
|
||||
std::string fileName = std::to_string(bucket) + "_01_wl.dat";
|
||||
fs::path fullpath = pathSmsgDir / fileName;
|
||||
|
||||
FILE *fp;
|
||||
@@ -3073,7 +3073,7 @@ int SecureMsgStore(unsigned char *pHeader, unsigned char *pPayload, uint32_t nPa
|
||||
return 1;
|
||||
};
|
||||
|
||||
std::string fileName = boost::lexical_cast<std::string>(bucket) + "_01.dat";
|
||||
std::string fileName = std::to_string(bucket) + "_01.dat";
|
||||
fs::path fullpath = pathSmsgDir / fileName;
|
||||
|
||||
FILE *fp;
|
||||
@@ -3468,7 +3468,7 @@ int SecureMsgEncrypt(SecureMessage& smsg, std::string& addressFrom, std::string&
|
||||
return 8;
|
||||
};
|
||||
|
||||
int lenComp = LZ4_compress((char*)message.c_str(), (char*)&vchCompressed[0], lenMsg);
|
||||
int lenComp = LZ4_compress_default((char*)message.c_str(), (char*)&vchCompressed[0], lenMsg, worstCase);
|
||||
if (lenComp < 1)
|
||||
{
|
||||
printf("Could not compress message data.\n");
|
||||
@@ -3674,7 +3674,7 @@ int SecureMsgSend(std::string& addressFrom, std::string& addressTo, std::string&
|
||||
std::string addressOutbox = "None";
|
||||
CTrianglesAddress coinAddrOutbox;
|
||||
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& entry, pwalletMain->mapAddressBook)
|
||||
for (const auto& entry : pwalletMain->mapAddressBook)
|
||||
{
|
||||
// -- get first owned address
|
||||
if (!IsMine(*pwalletMain, entry.first))
|
||||
|
||||
+3
-4
@@ -5,7 +5,6 @@
|
||||
#include "sync.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#ifdef DEBUG_LOCKCONTENTION
|
||||
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
|
||||
@@ -58,14 +57,14 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
|
||||
{
|
||||
printf("POTENTIAL DEADLOCK DETECTED\n");
|
||||
printf("Previous lock order was:\n");
|
||||
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
|
||||
for (const auto& i : s2)
|
||||
{
|
||||
if (i.first == mismatch.first) printf(" (1)");
|
||||
if (i.first == mismatch.second) printf(" (2)");
|
||||
printf(" %s\n", i.second.ToString().c_str());
|
||||
}
|
||||
printf("Current lock order is:\n");
|
||||
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
|
||||
for (const auto& i : s1)
|
||||
{
|
||||
if (i.first == mismatch.first) printf(" (1)");
|
||||
if (i.first == mismatch.second) printf(" (2)");
|
||||
@@ -84,7 +83,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
||||
(*lockstack).push_back(std::make_pair(c, locklocation));
|
||||
|
||||
if (!fTry) {
|
||||
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) {
|
||||
for (const auto& i : (*lockstack)) {
|
||||
if (i.first == c) break;
|
||||
|
||||
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// Unit tests for block-chain checkpoints
|
||||
//
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "../checkpoints.h"
|
||||
#include "../util.h"
|
||||
|
||||
+8
-11
@@ -3,10 +3,8 @@
|
||||
//
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
@@ -97,22 +95,21 @@ static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, in
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DoS_checknbits)
|
||||
{
|
||||
using namespace boost::assign; // for 'map_list_of()'
|
||||
|
||||
// Timestamps,nBits from the Triangles blockchain.
|
||||
// These are the block-chain checkpoint blocks
|
||||
typedef std::map<int64, unsigned int> BlockData;
|
||||
BlockData chainData =
|
||||
map_list_of(1239852051,486604799)(1262749024,486594666)
|
||||
(1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
|
||||
(1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
|
||||
(1313172719,436789733);
|
||||
BlockData chainData = {
|
||||
{1239852051,486604799},{1262749024,486594666},
|
||||
{1279305360,469854461},{1280200847,469830746},{1281678674,469809688},
|
||||
{1296207707,453179945},{1302624061,453036989},{1309640330,437004818},
|
||||
{1313172719,436789733},
|
||||
};
|
||||
|
||||
// Make sure CheckNBits considers every combination of block-chain-lock-in-points
|
||||
// "sane":
|
||||
BOOST_FOREACH(const BlockData::value_type& i, chainData)
|
||||
for (const BlockData::value_type& i : chainData)
|
||||
{
|
||||
BOOST_FOREACH(const BlockData::value_type& j, chainData)
|
||||
for (const BlockData::value_type& j : chainData)
|
||||
{
|
||||
BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "init.h"
|
||||
#include "wallet.h"
|
||||
@@ -16,7 +15,7 @@ GetResults(CWalletDB& walletdb, std::map<int64, CAccountingEntry>& results)
|
||||
results.clear();
|
||||
BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK);
|
||||
walletdb.ListAccountCreditDebit("", aes);
|
||||
BOOST_FOREACH(CAccountingEntry& ae, aes)
|
||||
for (CAccountingEntry& ae : aes)
|
||||
{
|
||||
results[ae.nOrderPos] = ae;
|
||||
}
|
||||
|
||||
+10
-10
@@ -16,7 +16,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
|
||||
{
|
||||
Array tests = read_json("base58_encode_decode.json");
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
|
||||
Array tests = read_json("base58_encode_decode.json");
|
||||
std::vector<unsigned char> result;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
@@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
|
||||
}
|
||||
|
||||
// Visitor to check address type
|
||||
class TestAddrTypeVisitor : public boost::static_visitor<bool>
|
||||
class TestAddrTypeVisitor
|
||||
{
|
||||
private:
|
||||
std::string exp_addrType;
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
};
|
||||
|
||||
// Visitor to check address payload
|
||||
class TestPayloadVisitor : public boost::static_visitor<bool>
|
||||
class TestPayloadVisitor
|
||||
{
|
||||
private:
|
||||
std::vector<unsigned char> exp_payload;
|
||||
@@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
// Save global state
|
||||
bool fTestNet_stored = fTestNet;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
@@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
BOOST_CHECK_MESSAGE(addr.IsValid(), "!IsValid:" + strTest);
|
||||
BOOST_CHECK_MESSAGE(addr.IsScript() == (exp_addrType == "script"), "isScript mismatch" + strTest);
|
||||
CTxDestination dest = addr.Get();
|
||||
BOOST_CHECK_MESSAGE(boost::apply_visitor(TestAddrTypeVisitor(exp_addrType), dest), "addrType mismatch" + strTest);
|
||||
BOOST_CHECK_MESSAGE(std::visit(TestAddrTypeVisitor(exp_addrType), dest), "addrType mismatch" + strTest);
|
||||
|
||||
// Public key must be invalid private key
|
||||
secret.SetString(exp_base58string);
|
||||
@@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
// Save global state
|
||||
bool fTestNet_stored = fTestNet;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
@@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
continue;
|
||||
}
|
||||
CTrianglesAddress addrOut;
|
||||
BOOST_CHECK_MESSAGE(boost::apply_visitor(CTrianglesAddressVisitor(&addrOut), dest), "encode dest: " + strTest);
|
||||
BOOST_CHECK_MESSAGE(std::visit(CTrianglesAddressVisitor(&addrOut), dest), "encode dest: " + strTest);
|
||||
BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string, "mismatch: " + strTest);
|
||||
}
|
||||
}
|
||||
@@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
// Visiting a CNoDestination must fail
|
||||
CTrianglesAddress dummyAddr;
|
||||
CTxDestination nodest = CNoDestination();
|
||||
BOOST_CHECK(!boost::apply_visitor(CTrianglesAddressVisitor(&dummyAddr), nodest));
|
||||
BOOST_CHECK(!std::visit(CTrianglesAddressVisitor(&dummyAddr), nodest));
|
||||
|
||||
// Restore global state
|
||||
fTestNet = fTestNet_stored;
|
||||
@@ -235,7 +235,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
||||
CTrianglesSecret secret;
|
||||
CTrianglesAddress addr;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "util.h"
|
||||
@@ -17,7 +16,7 @@ ResetArgs(const std::string& strArg)
|
||||
|
||||
// Convert to char*:
|
||||
std::vector<const char*> vecChar;
|
||||
BOOST_FOREACH(std::string& s, vecArg)
|
||||
for (std::string& s : vecArg)
|
||||
vecChar.push_back(s.c_str());
|
||||
|
||||
ParseParameters(vecChar.size(), &vecChar[0]);
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/assign/list_inserter.hpp>
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <tuple>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -15,7 +11,6 @@
|
||||
#include "wallet.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::assign;
|
||||
|
||||
typedef vector<unsigned char> valtype;
|
||||
|
||||
@@ -32,7 +27,7 @@ sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction,
|
||||
|
||||
CScript result;
|
||||
result << OP_0; // CHECKMULTISIG bug workaround
|
||||
BOOST_FOREACH(CKey key, keys)
|
||||
for (CKey key : keys)
|
||||
{
|
||||
vector<unsigned char> vchSig;
|
||||
BOOST_CHECK(key.Sign(hash, vchSig));
|
||||
@@ -78,19 +73,19 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||
|
||||
// Test a AND b:
|
||||
keys.clear();
|
||||
keys += key[0],key[1]; // magic operator+= from boost.assign
|
||||
keys.push_back(key[0]); keys.push_back(key[1]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0);
|
||||
BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, true, 0));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
keys.clear();
|
||||
keys += key[i];
|
||||
keys.push_back(key[i]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 1: %d", i));
|
||||
|
||||
keys.clear();
|
||||
keys += key[1],key[i];
|
||||
keys.push_back(key[1]); keys.push_back(key[i]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 2: %d", i));
|
||||
}
|
||||
@@ -99,7 +94,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
keys.clear();
|
||||
keys += key[i];
|
||||
keys.push_back(key[i]);
|
||||
s = sign_multisig(a_or_b, keys, txTo[1], 0);
|
||||
if (i == 0 || i == 1)
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i));
|
||||
@@ -118,7 +113,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
keys.clear();
|
||||
keys += key[i],key[j];
|
||||
keys.push_back(key[i]); keys.push_back(key[j]);
|
||||
s = sign_multisig(escrow, keys, txTo[2], 0);
|
||||
if (i < j && i < 3 && j < 3)
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 1: %d %d", i, j));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "base58.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/assign/list_inserter.hpp>
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "../main.h"
|
||||
#include "../script.h"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
@@ -48,7 +47,7 @@ ParseScript(string s)
|
||||
vector<string> words;
|
||||
split(words, s, is_any_of(" \t\n"), token_compress_on);
|
||||
|
||||
BOOST_FOREACH(string w, words)
|
||||
for (string w : words)
|
||||
{
|
||||
if (all(w, is_digit()) ||
|
||||
(starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
|
||||
@@ -128,7 +127,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
|
||||
// scripts.
|
||||
Array tests = read_json("script_valid.json");
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
string strTest = write_string(tv, false);
|
||||
@@ -152,7 +151,7 @@ BOOST_AUTO_TEST_CASE(script_invalid)
|
||||
// Scripts that should evaluate as invalid
|
||||
Array tests = read_json("script_invalid.json");
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
string strTest = write_string(tv, false);
|
||||
@@ -211,7 +210,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac
|
||||
// and vice-versa)
|
||||
//
|
||||
result << OP_0;
|
||||
BOOST_FOREACH(CKey key, keys)
|
||||
for (CKey key : keys)
|
||||
{
|
||||
vector<unsigned char> vchSig;
|
||||
BOOST_CHECK(key.Sign(hash, vchSig));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "script.h"
|
||||
#include "key.h"
|
||||
|
||||
@@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
|
||||
// ... where all scripts are stringified scripts.
|
||||
Array tests = read_json("tx_valid.json");
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
string strTest = write_string(tv, false);
|
||||
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
|
||||
map<COutPoint, CScript> mapprevOutScriptPubKeys;
|
||||
Array inputs = test[0].get_array();
|
||||
bool fValid = true;
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
for (Value& input : inputs)
|
||||
{
|
||||
if (input.type() != array_type)
|
||||
{
|
||||
@@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
|
||||
// ... where all scripts are stringified scripts.
|
||||
Array tests = read_json("tx_invalid.json");
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
for (Value& tv : tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
string strTest = write_string(tv, false);
|
||||
@@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
|
||||
map<COutPoint, CScript> mapprevOutScriptPubKeys;
|
||||
Array inputs = test[0].get_array();
|
||||
bool fValid = true;
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
for (Value& input : inputs)
|
||||
{
|
||||
if (input.type() != array_type)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
|
||||
@@ -42,7 +42,7 @@ static void add_coin(int64 nValue, int nAge = 6*24, bool fIsFromMe = false, int
|
||||
|
||||
static void empty_wallet(void)
|
||||
{
|
||||
BOOST_FOREACH(COutput output, vCoins)
|
||||
for (COutput output : vCoins)
|
||||
delete output.tx;
|
||||
vCoins.clear();
|
||||
}
|
||||
|
||||
-1692
File diff suppressed because it is too large
Load Diff
@@ -1,232 +0,0 @@
|
||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file address.h
|
||||
* \brief Headers for address.h
|
||||
**/
|
||||
|
||||
#ifndef TOR_ADDRESS_H
|
||||
#define TOR_ADDRESS_H
|
||||
|
||||
#include "orconfig.h"
|
||||
#include "torint.h"
|
||||
#include "tor_compat.h"
|
||||
|
||||
/** The number of bits from an address to consider while doing a masked
|
||||
* comparison. */
|
||||
typedef uint8_t maskbits_t;
|
||||
|
||||
struct in_addr;
|
||||
/** Holds an IPv4 or IPv6 address. (Uses less memory than struct
|
||||
* sockaddr_storage.) */
|
||||
typedef struct tor_addr_t
|
||||
{
|
||||
sa_family_t family;
|
||||
union {
|
||||
uint32_t dummy_; /* This field is here so we have something to initialize
|
||||
* with a reliable cross-platform type. */
|
||||
struct in_addr in_addr;
|
||||
struct in6_addr in6_addr;
|
||||
} addr;
|
||||
} tor_addr_t;
|
||||
|
||||
/** Holds an IP address and a TCP/UDP port. */
|
||||
typedef struct tor_addr_port_t
|
||||
{
|
||||
tor_addr_t addr;
|
||||
uint16_t port;
|
||||
} tor_addr_port_t;
|
||||
|
||||
#define TOR_ADDR_NULL {AF_UNSPEC, {0}}
|
||||
|
||||
static INLINE const struct in6_addr *tor_addr_to_in6(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_ipv4n(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_ipv4h(const tor_addr_t *a);
|
||||
static INLINE uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a);
|
||||
static INLINE sa_family_t tor_addr_family(const tor_addr_t *a);
|
||||
static INLINE const struct in_addr *tor_addr_to_in(const tor_addr_t *a);
|
||||
static INLINE int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u);
|
||||
|
||||
socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
|
||||
struct sockaddr *sa_out, socklen_t len);
|
||||
int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
|
||||
uint16_t *port_out);
|
||||
void tor_addr_make_unspec(tor_addr_t *a);
|
||||
void tor_addr_make_null(tor_addr_t *a, sa_family_t family);
|
||||
char *tor_sockaddr_to_str(const struct sockaddr *sa);
|
||||
|
||||
/** Return an in6_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not
|
||||
* an IPv6 address. */
|
||||
static INLINE const struct in6_addr *
|
||||
tor_addr_to_in6(const tor_addr_t *a)
|
||||
{
|
||||
return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
|
||||
}
|
||||
|
||||
/** Given an IPv6 address <b>x</b>, yield it as an array of uint8_t.
|
||||
*
|
||||
* Requires that <b>x</b> is actually an IPv6 address.
|
||||
*/
|
||||
#define tor_addr_to_in6_addr8(x) tor_addr_to_in6(x)->s6_addr
|
||||
/** Given an IPv6 address <b>x</b>, yield it as an array of uint16_t.
|
||||
*
|
||||
* Requires that <b>x</b> is actually an IPv6 address.
|
||||
*/
|
||||
#define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6(x))
|
||||
/** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t.
|
||||
*
|
||||
* Requires that <b>x</b> is actually an IPv6 address.
|
||||
*/
|
||||
#define tor_addr_to_in6_addr32(x) S6_ADDR32(*tor_addr_to_in6(x))
|
||||
|
||||
/** Return an IPv4 address in network order for <b>a</b>, or 0 if
|
||||
* <b>a</b> is not an IPv4 address. */
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_ipv4n(const tor_addr_t *a)
|
||||
{
|
||||
return a->family == AF_INET ? a->addr.in_addr.s_addr : 0;
|
||||
}
|
||||
/** Return an IPv4 address in host order for <b>a</b>, or 0 if
|
||||
* <b>a</b> is not an IPv4 address. */
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_ipv4h(const tor_addr_t *a)
|
||||
{
|
||||
return ntohl(tor_addr_to_ipv4n(a));
|
||||
}
|
||||
/** Given an IPv6 address, return its mapped IPv4 address in host order, or
|
||||
* 0 if <b>a</b> is not an IPv6 address.
|
||||
*
|
||||
* (Does not check whether the address is really a mapped address */
|
||||
static INLINE uint32_t
|
||||
tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
|
||||
{
|
||||
return a->family == AF_INET6 ? ntohl(tor_addr_to_in6_addr32(a)[3]) : 0;
|
||||
}
|
||||
/** Return the address family of <b>a</b>. Possible values are:
|
||||
* AF_INET6, AF_INET, AF_UNSPEC. */
|
||||
static INLINE sa_family_t
|
||||
tor_addr_family(const tor_addr_t *a)
|
||||
{
|
||||
return a->family;
|
||||
}
|
||||
/** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not
|
||||
* an IPv4 address. */
|
||||
static INLINE const struct in_addr *
|
||||
tor_addr_to_in(const tor_addr_t *a)
|
||||
{
|
||||
return a->family == AF_INET ? &a->addr.in_addr : NULL;
|
||||
}
|
||||
/** Return true iff <b>a</b> is an IPv4 address equal to the host-ordered
|
||||
* address in <b>u</b>. */
|
||||
static INLINE int
|
||||
tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
|
||||
{
|
||||
return a->family == AF_INET ? (tor_addr_to_ipv4h(a) == u) : 0;
|
||||
}
|
||||
|
||||
/** Length of a buffer that you need to allocate to be sure you can encode
|
||||
* any tor_addr_t.
|
||||
*
|
||||
* This allows enough space for
|
||||
* "[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]",
|
||||
* plus a terminating NUL.
|
||||
*/
|
||||
#define TOR_ADDR_BUF_LEN 48
|
||||
|
||||
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
|
||||
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
|
||||
|
||||
/** Wrapper function of fmt_addr_impl(). It does not decorate IPv6
|
||||
* addresses. */
|
||||
#define fmt_addr(a) fmt_addr_impl((a), 0)
|
||||
/** Wrapper function of fmt_addr_impl(). It decorates IPv6
|
||||
* addresses. */
|
||||
#define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1)
|
||||
const char *fmt_addr_impl(const tor_addr_t *addr, int decorate);
|
||||
const char *fmt_addrport(const tor_addr_t *addr, uint16_t port);
|
||||
const char * fmt_addr32(uint32_t addr);
|
||||
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
|
||||
|
||||
/** Flag to specify how to do a comparison between addresses. In an "exact"
|
||||
* comparison, addresses are equivalent only if they are in the same family
|
||||
* with the same value. In a "semantic" comparison, IPv4 addresses match all
|
||||
* IPv6 encodings of those addresses. */
|
||||
typedef enum {
|
||||
CMP_EXACT,
|
||||
CMP_SEMANTIC,
|
||||
} tor_addr_comparison_t;
|
||||
|
||||
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
tor_addr_comparison_t how);
|
||||
int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||
maskbits_t mask, tor_addr_comparison_t how);
|
||||
/** Return true iff a and b are the same address. The comparison is done
|
||||
* "exactly". */
|
||||
#define tor_addr_eq(a,b) (0==tor_addr_compare((a),(b),CMP_EXACT))
|
||||
|
||||
unsigned int tor_addr_hash(const tor_addr_t *addr);
|
||||
int tor_addr_is_v4(const tor_addr_t *addr);
|
||||
int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
|
||||
const char *filename, int lineno);
|
||||
#define tor_addr_is_internal(addr, for_listening) \
|
||||
tor_addr_is_internal_((addr), (for_listening), SHORT_FILE__, __LINE__)
|
||||
|
||||
/** Longest length that can be required for a reverse lookup name. */
|
||||
/* 32 nybbles, 32 dots, 8 characters of "ip6.arpa", 1 NUL: 73 characters. */
|
||||
#define REVERSE_LOOKUP_NAME_BUF_LEN 73
|
||||
int tor_addr_to_PTR_name(char *out, size_t outlen,
|
||||
const tor_addr_t *addr);
|
||||
int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
|
||||
int family, int accept_regular);
|
||||
|
||||
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out,
|
||||
uint16_t *port_out);
|
||||
#define TAPMP_EXTENDED_STAR 1
|
||||
int tor_addr_parse_mask_ports(const char *s, unsigned flags,
|
||||
tor_addr_t *addr_out, maskbits_t *mask_out,
|
||||
uint16_t *port_min_out, uint16_t *port_max_out);
|
||||
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len,
|
||||
int decorate);
|
||||
int tor_addr_parse(tor_addr_t *addr, const char *src);
|
||||
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
|
||||
void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
|
||||
/** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host
|
||||
* order. */
|
||||
#define tor_addr_from_ipv4h(dest, v4addr) \
|
||||
tor_addr_from_ipv4n((dest), htonl(v4addr))
|
||||
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes);
|
||||
/** Set <b>dest</b> to the IPv4 address incoded in <b>in</b>. */
|
||||
#define tor_addr_from_in(dest, in) \
|
||||
tor_addr_from_ipv4n((dest), (in)->s_addr);
|
||||
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
|
||||
int tor_addr_is_null(const tor_addr_t *addr);
|
||||
int tor_addr_is_loopback(const tor_addr_t *addr);
|
||||
|
||||
int tor_addr_port_split(int severity, const char *addrport,
|
||||
char **address_out, uint16_t *port_out);
|
||||
|
||||
int tor_addr_port_parse(int severity, const char *addrport,
|
||||
tor_addr_t *address_out, uint16_t *port_out);
|
||||
|
||||
int tor_addr_hostname_is_local(const char *name);
|
||||
|
||||
/* IPv4 helpers */
|
||||
int is_internal_IP(uint32_t ip, int for_listening);
|
||||
int addr_port_lookup(int severity, const char *addrport, char **address,
|
||||
uint32_t *addr, uint16_t *port_out);
|
||||
int parse_port_range(const char *port, uint16_t *port_min_out,
|
||||
uint16_t *port_max_out);
|
||||
int addr_mask_get_bits(uint32_t mask);
|
||||
/** Length of a buffer to allocate to hold the results of tor_inet_ntoa.*/
|
||||
#define INET_NTOA_BUF_LEN 16
|
||||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
||||
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
|
||||
int get_interface_address(int severity, uint32_t *addr);
|
||||
|
||||
tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#ifndef TOR_ADDRESSMAP_H
|
||||
#define TOR_ADDRESSMAP_H
|
||||
|
||||
#include "testsupport.h"
|
||||
|
||||
void addressmap_init(void);
|
||||
void addressmap_clear_excluded_trackexithosts(const or_options_t *options);
|
||||
void addressmap_clear_invalid_automaps(const or_options_t *options);
|
||||
void addressmap_clean(time_t now);
|
||||
void addressmap_clear_configured(void);
|
||||
void addressmap_clear_transient(void);
|
||||
void addressmap_free_all(void);
|
||||
#define AMR_FLAG_USE_IPV4_DNS (1u<<0)
|
||||
#define AMR_FLAG_USE_IPV6_DNS (1u<<1)
|
||||
int addressmap_rewrite(char *address, size_t maxlen, unsigned flags,
|
||||
time_t *expires_out,
|
||||
addressmap_entry_source_t *exit_source_out);
|
||||
int addressmap_rewrite_reverse(char *address, size_t maxlen, unsigned flags,
|
||||
time_t *expires_out);
|
||||
int addressmap_have_mapping(const char *address, int update_timeout);
|
||||
|
||||
void addressmap_register(const char *address, char *new_address,
|
||||
time_t expires, addressmap_entry_source_t source,
|
||||
const int address_wildcard,
|
||||
const int new_address_wildcard);
|
||||
int parse_virtual_addr_network(const char *val,
|
||||
sa_family_t family, int validate_only,
|
||||
char **msg);
|
||||
int client_dns_incr_failures(const char *address);
|
||||
void client_dns_clear_failures(const char *address);
|
||||
void client_dns_set_addressmap(entry_connection_t *for_conn,
|
||||
const char *address, const tor_addr_t *val,
|
||||
const char *exitname, int ttl);
|
||||
const char *addressmap_register_virtual_address(int type, char *new_address);
|
||||
void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
|
||||
time_t max_expires, int want_expiry);
|
||||
int address_is_in_virtual_range(const char *addr);
|
||||
void clear_trackexithost_mappings(const char *exitname);
|
||||
void client_dns_set_reverse_addressmap(entry_connection_t *for_conn,
|
||||
const char *address, const char *v,
|
||||
const char *exitname, int ttl);
|
||||
int addressmap_address_should_automap(const char *address,
|
||||
const or_options_t *options);
|
||||
|
||||
#ifdef ADDRESSMAP_PRIVATE
|
||||
typedef struct virtual_addr_conf_t {
|
||||
tor_addr_t addr;
|
||||
maskbits_t bits;
|
||||
} virtual_addr_conf_t;
|
||||
|
||||
STATIC void get_random_virtual_addr(const virtual_addr_conf_t *conf,
|
||||
tor_addr_t *addr_out);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
-523
@@ -1,523 +0,0 @@
|
||||
/* Copyright (c) 2001, Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file aes.c
|
||||
* \brief Implements a counter-mode stream cipher on top of AES.
|
||||
**/
|
||||
|
||||
#include "orconfig.h"
|
||||
|
||||
#ifdef _WIN32 /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1300)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "crypto.h"
|
||||
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0)
|
||||
/* See comments about which counter mode implementation to use below. */
|
||||
#include <openssl/modes.h>
|
||||
#define CAN_USE_OPENSSL_CTR
|
||||
#endif
|
||||
#include "tor_compat.h"
|
||||
#include "aes.h"
|
||||
#include "tor_util.h"
|
||||
#include "torlog.h"
|
||||
#include "di_ops.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
/* Android's OpenSSL seems to have removed all of its Engine support. */
|
||||
#define DISABLE_ENGINES
|
||||
#endif
|
||||
|
||||
/* We have five strategies for implementing AES counter mode.
|
||||
*
|
||||
* Best with x86 and x86_64: Use EVP_aes_ctr128() and EVP_EncryptUpdate().
|
||||
* This is possible with OpenSSL 1.0.1, where the counter-mode implementation
|
||||
* can use bit-sliced or vectorized AES or AESNI as appropriate.
|
||||
*
|
||||
* Otherwise: Pick the best possible AES block implementation that OpenSSL
|
||||
* gives us, and the best possible counter-mode implementation, and combine
|
||||
* them.
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) && \
|
||||
(defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__)) \
|
||||
|
||||
#define USE_EVP_AES_CTR
|
||||
|
||||
#endif
|
||||
|
||||
/* We have 2 strategies for getting the AES block cipher: Via OpenSSL's
|
||||
* AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function.
|
||||
*
|
||||
* If there's any hardware acceleration in play, we want to be using EVP_* so
|
||||
* we can get it. Otherwise, we'll want AES_*, which seems to be about 5%
|
||||
* faster than indirecting through the EVP layer.
|
||||
*/
|
||||
|
||||
/* We have 2 strategies for getting a plug-in counter mode: use our own, or
|
||||
* use OpenSSL's.
|
||||
*
|
||||
* Here we have a counter mode that's faster than the one shipping with
|
||||
* OpenSSL pre-1.0 (by about 10%!). But OpenSSL 1.0.0 added a counter mode
|
||||
* implementation faster than the one here (by about 7%). So we pick which
|
||||
* one to used based on the Openssl version above. (OpenSSL 1.0.0a fixed a
|
||||
* critical bug in that counter mode implementation, so we need to test to
|
||||
* make sure that we have a fixed version.)
|
||||
*/
|
||||
|
||||
#ifdef USE_EVP_AES_CTR
|
||||
|
||||
struct aes_cnt_cipher {
|
||||
EVP_CIPHER_CTX *evp;
|
||||
};
|
||||
|
||||
aes_cnt_cipher_t *
|
||||
aes_new_cipher(const char *key, const char *iv)
|
||||
{
|
||||
aes_cnt_cipher_t *cipher;
|
||||
cipher = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
|
||||
cipher->evp = EVP_CIPHER_CTX_new();
|
||||
EVP_EncryptInit(cipher->evp, EVP_aes_128_ctr(),
|
||||
(const unsigned char*)key, (const unsigned char *)iv);
|
||||
return cipher;
|
||||
}
|
||||
void
|
||||
aes_cipher_free(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
if (!cipher)
|
||||
return;
|
||||
EVP_CIPHER_CTX_free(cipher->evp);
|
||||
memwipe(cipher, 0, sizeof(aes_cnt_cipher_t));
|
||||
tor_free(cipher);
|
||||
}
|
||||
void
|
||||
aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
|
||||
char *output)
|
||||
{
|
||||
int outl;
|
||||
|
||||
tor_assert(len < INT_MAX);
|
||||
|
||||
EVP_EncryptUpdate(cipher->evp, (unsigned char*)output,
|
||||
&outl, (const unsigned char *)input, (int)len);
|
||||
}
|
||||
void
|
||||
aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
|
||||
{
|
||||
int outl;
|
||||
|
||||
tor_assert(len < INT_MAX);
|
||||
|
||||
EVP_EncryptUpdate(cipher->evp, (unsigned char*)data,
|
||||
&outl, (unsigned char*)data, (int)len);
|
||||
}
|
||||
int
|
||||
evaluate_evp_for_aes(int force_val)
|
||||
{
|
||||
(void) force_val;
|
||||
log_info(LD_CRYPTO, "This version of OpenSSL has a known-good EVP "
|
||||
"counter-mode implementation. Using it.");
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
evaluate_ctr_for_aes(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
/*======================================================================*/
|
||||
/* Interface to AES code, and counter implementation */
|
||||
|
||||
/** Implements an AES counter-mode cipher. */
|
||||
struct aes_cnt_cipher {
|
||||
/** This next element (however it's defined) is the AES key. */
|
||||
union {
|
||||
EVP_CIPHER_CTX evp;
|
||||
AES_KEY aes;
|
||||
} key;
|
||||
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
#define USING_COUNTER_VARS
|
||||
/** These four values, together, implement a 128-bit counter, with
|
||||
* counter0 as the low-order word and counter3 as the high-order word. */
|
||||
uint32_t counter3;
|
||||
uint32_t counter2;
|
||||
uint32_t counter1;
|
||||
uint32_t counter0;
|
||||
#endif
|
||||
|
||||
union {
|
||||
/** The counter, in big-endian order, as bytes. */
|
||||
uint8_t buf[16];
|
||||
/** The counter, in big-endian order, as big-endian words. Note that
|
||||
* on big-endian platforms, this is redundant with counter3...0,
|
||||
* so we just use these values instead. */
|
||||
uint32_t buf32[4];
|
||||
} ctr_buf;
|
||||
|
||||
/** The encrypted value of ctr_buf. */
|
||||
uint8_t buf[16];
|
||||
/** Our current stream position within buf. */
|
||||
unsigned int pos;
|
||||
|
||||
/** True iff we're using the evp implementation of this cipher. */
|
||||
uint8_t using_evp;
|
||||
};
|
||||
|
||||
/** True iff we should prefer the EVP implementation for AES, either because
|
||||
* we're testing it or because we have hardware acceleration configured */
|
||||
static int should_use_EVP = 0;
|
||||
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
/** True iff we have tested the counter-mode implementation and found that it
|
||||
* doesn't have the counter-mode bug from OpenSSL 1.0.0. */
|
||||
static int should_use_openssl_CTR = 0;
|
||||
#endif
|
||||
|
||||
/** Check whether we should use the EVP interface for AES. If <b>force_val</b>
|
||||
* is nonnegative, we use use EVP iff it is true. Otherwise, we use EVP
|
||||
* if there is an engine enabled for aes-ecb. */
|
||||
int
|
||||
evaluate_evp_for_aes(int force_val)
|
||||
{
|
||||
ENGINE *e;
|
||||
|
||||
if (force_val >= 0) {
|
||||
should_use_EVP = force_val;
|
||||
return 0;
|
||||
}
|
||||
#ifdef DISABLE_ENGINES
|
||||
should_use_EVP = 0;
|
||||
#else
|
||||
e = ENGINE_get_cipher_engine(NID_aes_128_ecb);
|
||||
|
||||
if (e) {
|
||||
log_info(LD_CRYPTO, "AES engine \"%s\" found; using EVP_* functions.",
|
||||
ENGINE_get_name(e));
|
||||
should_use_EVP = 1;
|
||||
} else {
|
||||
log_info(LD_CRYPTO, "No AES engine found; using AES_* functions.");
|
||||
should_use_EVP = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Test the OpenSSL counter mode implementation to see whether it has the
|
||||
* counter-mode bug from OpenSSL 1.0.0. If the implementation works, then
|
||||
* we will use it for future encryption/decryption operations.
|
||||
*
|
||||
* We can't just look at the OpenSSL version, since some distributions update
|
||||
* their OpenSSL packages without changing the version number.
|
||||
**/
|
||||
int
|
||||
evaluate_ctr_for_aes(void)
|
||||
{
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
/* Result of encrypting an all-zero block with an all-zero 128-bit AES key.
|
||||
* This should be the same as encrypting an all-zero block with an all-zero
|
||||
* 128-bit AES key in counter mode, starting at position 0 of the stream.
|
||||
*/
|
||||
static const unsigned char encrypt_zero[] =
|
||||
"\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e";
|
||||
unsigned char zero[16];
|
||||
unsigned char output[16];
|
||||
unsigned char ivec[16];
|
||||
unsigned char ivec_tmp[16];
|
||||
unsigned int pos, i;
|
||||
AES_KEY key;
|
||||
memset(zero, 0, sizeof(zero));
|
||||
memset(ivec, 0, sizeof(ivec));
|
||||
AES_set_encrypt_key(zero, 128, &key);
|
||||
|
||||
pos = 0;
|
||||
/* Encrypting a block one byte at a time should make the error manifest
|
||||
* itself for known bogus openssl versions. */
|
||||
for (i=0; i<16; ++i)
|
||||
AES_ctr128_encrypt(&zero[i], &output[i], 1, &key, ivec, ivec_tmp, &pos);
|
||||
|
||||
if (fast_memneq(output, encrypt_zero, 16)) {
|
||||
/* Counter mode is buggy */
|
||||
log_notice(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
|
||||
"not using it.");
|
||||
} else {
|
||||
/* Counter mode is okay */
|
||||
log_info(LD_CRYPTO, "This OpenSSL has a good implementation of counter "
|
||||
"mode; using it.");
|
||||
should_use_openssl_CTR = 1;
|
||||
}
|
||||
#else
|
||||
log_info(LD_CRYPTO, "This version of OpenSSL has a slow implementation of "
|
||||
"counter mode; not using it.");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(USING_COUNTER_VARS)
|
||||
#define COUNTER(c, n) ((c)->ctr_buf.buf32[3-(n)])
|
||||
#else
|
||||
#define COUNTER(c, n) ((c)->counter ## n)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper function: set <b>cipher</b>'s internal buffer to the encrypted
|
||||
* value of the current counter.
|
||||
*/
|
||||
static INLINE void
|
||||
aes_fill_buf_(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
/* We don't currently use OpenSSL's counter mode implementation because:
|
||||
* 1) some versions have known bugs
|
||||
* 2) its attitude towards IVs is not our own
|
||||
* 3) changing the counter position was not trivial, last time I looked.
|
||||
* None of these issues are insurmountable in principle.
|
||||
*/
|
||||
|
||||
if (cipher->using_evp) {
|
||||
int outl=16, inl=16;
|
||||
EVP_EncryptUpdate(&cipher->key.evp, cipher->buf, &outl,
|
||||
cipher->ctr_buf.buf, inl);
|
||||
} else {
|
||||
AES_encrypt(cipher->ctr_buf.buf, cipher->buf, &cipher->key.aes);
|
||||
}
|
||||
}
|
||||
|
||||
static void aes_set_key(aes_cnt_cipher_t *cipher, const char *key,
|
||||
int key_bits);
|
||||
static void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv);
|
||||
|
||||
/**
|
||||
* Return a newly allocated counter-mode AES128 cipher implementation,
|
||||
* using the 128-bit key <b>key</b> and the 128-bit IV <b>iv</b>.
|
||||
*/
|
||||
aes_cnt_cipher_t*
|
||||
aes_new_cipher(const char *key, const char *iv)
|
||||
{
|
||||
aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
|
||||
|
||||
aes_set_key(result, key, 128);
|
||||
aes_set_iv(result, iv);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Set the key of <b>cipher</b> to <b>key</b>, which is
|
||||
* <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets
|
||||
* the counter to 0.
|
||||
*/
|
||||
static void
|
||||
aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
|
||||
{
|
||||
if (should_use_EVP) {
|
||||
const EVP_CIPHER *c;
|
||||
switch (key_bits) {
|
||||
case 128: c = EVP_aes_128_ecb(); break;
|
||||
case 192: c = EVP_aes_192_ecb(); break;
|
||||
case 256: c = EVP_aes_256_ecb(); break;
|
||||
default: tor_assert(0);
|
||||
}
|
||||
EVP_EncryptInit(&cipher->key.evp, c, (const unsigned char*)key, NULL);
|
||||
cipher->using_evp = 1;
|
||||
} else {
|
||||
AES_set_encrypt_key((const unsigned char *)key, key_bits,&cipher->key.aes);
|
||||
cipher->using_evp = 0;
|
||||
}
|
||||
|
||||
#ifdef USING_COUNTER_VARS
|
||||
cipher->counter0 = 0;
|
||||
cipher->counter1 = 0;
|
||||
cipher->counter2 = 0;
|
||||
cipher->counter3 = 0;
|
||||
#endif
|
||||
|
||||
memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
|
||||
|
||||
cipher->pos = 0;
|
||||
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
if (should_use_openssl_CTR)
|
||||
memset(cipher->buf, 0, sizeof(cipher->buf));
|
||||
else
|
||||
#endif
|
||||
aes_fill_buf_(cipher);
|
||||
}
|
||||
|
||||
/** Release storage held by <b>cipher</b>
|
||||
*/
|
||||
void
|
||||
aes_cipher_free(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
if (!cipher)
|
||||
return;
|
||||
if (cipher->using_evp) {
|
||||
EVP_CIPHER_CTX_cleanup(&cipher->key.evp);
|
||||
}
|
||||
memwipe(cipher, 0, sizeof(aes_cnt_cipher_t));
|
||||
tor_free(cipher);
|
||||
}
|
||||
|
||||
#if defined(USING_COUNTER_VARS)
|
||||
#define UPDATE_CTR_BUF(c, n) STMT_BEGIN \
|
||||
(c)->ctr_buf.buf32[3-(n)] = htonl((c)->counter ## n); \
|
||||
STMT_END
|
||||
#else
|
||||
#define UPDATE_CTR_BUF(c, n)
|
||||
#endif
|
||||
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
/* Helper function to use EVP with openssl's counter-mode wrapper. */
|
||||
static void
|
||||
evp_block128_fn(const uint8_t in[16],
|
||||
uint8_t out[16],
|
||||
const void *key)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx = (void*)key;
|
||||
int inl=16, outl=16;
|
||||
EVP_EncryptUpdate(ctx, out, &outl, in, inl);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Encrypt <b>len</b> bytes from <b>input</b>, storing the result in
|
||||
* <b>output</b>. Uses the key in <b>cipher</b>, and advances the counter
|
||||
* by <b>len</b> bytes as it encrypts.
|
||||
*/
|
||||
void
|
||||
aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
|
||||
char *output)
|
||||
{
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
if (should_use_openssl_CTR) {
|
||||
if (cipher->using_evp) {
|
||||
/* In openssl 1.0.0, there's an if'd out EVP_aes_128_ctr in evp.h. If
|
||||
* it weren't disabled, it might be better just to use that.
|
||||
*/
|
||||
CRYPTO_ctr128_encrypt((const unsigned char *)input,
|
||||
(unsigned char *)output,
|
||||
len,
|
||||
&cipher->key.evp,
|
||||
cipher->ctr_buf.buf,
|
||||
cipher->buf,
|
||||
&cipher->pos,
|
||||
evp_block128_fn);
|
||||
} else {
|
||||
AES_ctr128_encrypt((const unsigned char *)input,
|
||||
(unsigned char *)output,
|
||||
len,
|
||||
&cipher->key.aes,
|
||||
cipher->ctr_buf.buf,
|
||||
cipher->buf,
|
||||
&cipher->pos);
|
||||
}
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
int c = cipher->pos;
|
||||
if (PREDICT_UNLIKELY(!len)) return;
|
||||
|
||||
while (1) {
|
||||
do {
|
||||
if (len-- == 0) { cipher->pos = c; return; }
|
||||
*(output++) = *(input++) ^ cipher->buf[c];
|
||||
} while (++c != 16);
|
||||
cipher->pos = c = 0;
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
|
||||
++COUNTER(cipher, 3);
|
||||
UPDATE_CTR_BUF(cipher, 3);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 2);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 1);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 0);
|
||||
aes_fill_buf_(cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Encrypt <b>len</b> bytes from <b>input</b>, storing the results in place.
|
||||
* Uses the key in <b>cipher</b>, and advances the counter by <b>len</b> bytes
|
||||
* as it encrypts.
|
||||
*/
|
||||
void
|
||||
aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
|
||||
{
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
if (should_use_openssl_CTR) {
|
||||
aes_crypt(cipher, data, len, data);
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
int c = cipher->pos;
|
||||
if (PREDICT_UNLIKELY(!len)) return;
|
||||
|
||||
while (1) {
|
||||
do {
|
||||
if (len-- == 0) { cipher->pos = c; return; }
|
||||
*(data++) ^= cipher->buf[c];
|
||||
} while (++c != 16);
|
||||
cipher->pos = c = 0;
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
|
||||
if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
|
||||
++COUNTER(cipher, 3);
|
||||
UPDATE_CTR_BUF(cipher, 3);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 2);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 1);
|
||||
}
|
||||
UPDATE_CTR_BUF(cipher, 0);
|
||||
aes_fill_buf_(cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Reset the 128-bit counter of <b>cipher</b> to the 16-bit big-endian value
|
||||
* in <b>iv</b>. */
|
||||
static void
|
||||
aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv)
|
||||
{
|
||||
#ifdef USING_COUNTER_VARS
|
||||
cipher->counter3 = ntohl(get_uint32(iv));
|
||||
cipher->counter2 = ntohl(get_uint32(iv+4));
|
||||
cipher->counter1 = ntohl(get_uint32(iv+8));
|
||||
cipher->counter0 = ntohl(get_uint32(iv+12));
|
||||
#endif
|
||||
cipher->pos = 0;
|
||||
memcpy(cipher->ctr_buf.buf, iv, 16);
|
||||
|
||||
#ifdef CAN_USE_OPENSSL_CTR
|
||||
if (!should_use_openssl_CTR)
|
||||
#endif
|
||||
aes_fill_buf_(cipher);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/* Copyright (c) 2003, Roger Dingledine
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/* Implements a minimal interface to counter-mode AES. */
|
||||
|
||||
#ifndef TOR_AES_H
|
||||
#define TOR_AES_H
|
||||
|
||||
/**
|
||||
* \file aes.h
|
||||
* \brief Headers for aes.c
|
||||
*/
|
||||
|
||||
struct aes_cnt_cipher;
|
||||
typedef struct aes_cnt_cipher aes_cnt_cipher_t;
|
||||
|
||||
aes_cnt_cipher_t* aes_new_cipher(const char *key, const char *iv);
|
||||
void aes_cipher_free(aes_cnt_cipher_t *cipher);
|
||||
void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
|
||||
char *output);
|
||||
void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
|
||||
|
||||
int evaluate_evp_for_aes(int force_value);
|
||||
int evaluate_ctr_for_aes(void);
|
||||
|
||||
#endif
|
||||
|
||||
-1072
File diff suppressed because it is too large
Load Diff
@@ -1,205 +0,0 @@
|
||||
/* Copyright (c) 2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#define __USE_GNU
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include "orconfig.h"
|
||||
#include "backtrace.h"
|
||||
#include "tor_compat.h"
|
||||
#include "tor_util.h"
|
||||
#include "torlog.h"
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CYGWIN_SIGNAL_H
|
||||
#include <cygwin/signal.h>
|
||||
#elif defined(HAVE_SYS_UCONTEXT_H)
|
||||
#include <sys/ucontext.h>
|
||||
#elif defined(HAVE_UCONTEXT_H)
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
|
||||
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
||||
#define USE_BACKTRACE
|
||||
#endif
|
||||
|
||||
#if !defined(USE_BACKTRACE)
|
||||
#define NO_BACKTRACE_IMPL
|
||||
#endif
|
||||
|
||||
/** Version of Tor to report in backtrace messages. */
|
||||
static char *bt_version = NULL;
|
||||
|
||||
#ifdef USE_BACKTRACE
|
||||
/** Largest stack depth to try to dump. */
|
||||
#define MAX_DEPTH 256
|
||||
/** Static allocation of stack to dump. This is static so we avoid stack
|
||||
* pressure. */
|
||||
static void *cb_buf[MAX_DEPTH];
|
||||
|
||||
/** Change a stacktrace in <b>stack</b> of depth <b>depth</b> so that it will
|
||||
* log the correct function from which a signal was received with context
|
||||
* <b>ctx</b>. (When we get a signal, the current function will not have
|
||||
* called any other function, and will therefore have not pushed its address
|
||||
* onto the stack. Fortunately, we usually have the program counter in the
|
||||
* ucontext_t structure.
|
||||
*/
|
||||
static void
|
||||
clean_backtrace(void **stack, int depth, const ucontext_t *ctx)
|
||||
{
|
||||
#ifdef PC_FROM_UCONTEXT
|
||||
#if defined(__linux__)
|
||||
const int n = 1;
|
||||
#elif defined(__darwin__) || defined(__APPLE__) || defined(__OpenBSD__) \
|
||||
|| defined(__FreeBSD__)
|
||||
const int n = 2;
|
||||
#else
|
||||
const int n = 1;
|
||||
#endif
|
||||
if (depth <= n)
|
||||
return;
|
||||
|
||||
stack[n] = (void*) ctx->PC_FROM_UCONTEXT;
|
||||
#else
|
||||
(void) depth;
|
||||
(void) ctx;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow
|
||||
* that with a backtrace log. */
|
||||
void
|
||||
log_backtrace(int severity, int domain, const char *msg)
|
||||
{
|
||||
int depth = backtrace(cb_buf, MAX_DEPTH);
|
||||
char **symbols = backtrace_symbols(cb_buf, depth);
|
||||
int i;
|
||||
tor_log(severity, domain, "%s. Stack trace:", msg);
|
||||
if (!symbols) {
|
||||
tor_log(severity, domain, " Unable to generate backtrace.");
|
||||
return;
|
||||
}
|
||||
for (i=0; i < depth; ++i) {
|
||||
tor_log(severity, domain, " %s", symbols[i]);
|
||||
}
|
||||
free(symbols);
|
||||
}
|
||||
|
||||
static void crash_handler(int sig, siginfo_t *si, void *ctx_)
|
||||
__attribute__((noreturn));
|
||||
|
||||
/** Signal handler: write a crash message with a stack trace, and die. */
|
||||
static void
|
||||
crash_handler(int sig, siginfo_t *si, void *ctx_)
|
||||
{
|
||||
char buf[40];
|
||||
int depth;
|
||||
ucontext_t *ctx = (ucontext_t *) ctx_;
|
||||
int n_fds, i;
|
||||
const int *fds = NULL;
|
||||
|
||||
(void) si;
|
||||
|
||||
depth = backtrace(cb_buf, MAX_DEPTH);
|
||||
/* Clean up the top stack frame so we get the real function
|
||||
* name for the most recently failing function. */
|
||||
clean_backtrace(cb_buf, depth, ctx);
|
||||
|
||||
format_dec_number_sigsafe((unsigned)sig, buf, sizeof(buf));
|
||||
|
||||
tor_log_err_sigsafe(bt_version, " died: Caught signal ", buf, "\n",
|
||||
NULL);
|
||||
|
||||
n_fds = tor_log_get_sigsafe_err_fds(&fds);
|
||||
for (i=0; i < n_fds; ++i)
|
||||
backtrace_symbols_fd(cb_buf, depth, fds[i]);
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
/** Install signal handlers as needed so that when we crash, we produce a
|
||||
* useful stack trace. Return 0 on success, -1 on failure. */
|
||||
static int
|
||||
install_bt_handler(void)
|
||||
{
|
||||
int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS,
|
||||
SIGIO, -1 };
|
||||
int i, rv=0;
|
||||
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = crash_handler;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigfillset(&sa.sa_mask);
|
||||
|
||||
for (i = 0; trap_signals[i] >= 0; ++i) {
|
||||
if (sigaction(trap_signals[i], &sa, NULL) == -1) {
|
||||
log_warn(LD_BUG, "Sigaction failed: %s", strerror(errno));
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Uninstall crash handlers. */
|
||||
static void
|
||||
remove_bt_handler(void)
|
||||
{
|
||||
/* We don't need to actually free anything at exit here. */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NO_BACKTRACE_IMPL
|
||||
void
|
||||
log_backtrace(int severity, int domain, const char *msg)
|
||||
{
|
||||
tor_log(severity, domain, "%s. (Stack trace not available)", msg);
|
||||
}
|
||||
|
||||
static int
|
||||
install_bt_handler(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_bt_handler(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Set up code to handle generating error messages on crashes. */
|
||||
int
|
||||
configure_backtrace_handler(const char *tor_version)
|
||||
{
|
||||
tor_free(bt_version);
|
||||
if (!tor_version)
|
||||
tor_version = "";
|
||||
tor_asprintf(&bt_version, "Tor %s", tor_version);
|
||||
|
||||
return install_bt_handler();
|
||||
}
|
||||
|
||||
/** Perform end-of-process cleanup for code that generates error messages on
|
||||
* crashes. */
|
||||
void
|
||||
clean_up_backtrace_handler(void)
|
||||
{
|
||||
remove_bt_handler();
|
||||
|
||||
tor_free(bt_version);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/* Copyright (c) 2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#ifndef TOR_BACKTRACE_H
|
||||
#define TOR_BACKTRACE_H
|
||||
|
||||
void log_backtrace(int severity, int domain, const char *msg);
|
||||
int configure_backtrace_handler(const char *tor_version);
|
||||
void clean_up_backtrace_handler(void);
|
||||
|
||||
#endif
|
||||
|
||||
-2584
File diff suppressed because it is too large
Load Diff
@@ -1,106 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file buffers.h
|
||||
* \brief Header file for buffers.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_BUFFERS_H
|
||||
#define TOR_BUFFERS_H
|
||||
|
||||
#include "testsupport.h"
|
||||
|
||||
buf_t *buf_new(void);
|
||||
buf_t *buf_new_with_capacity(size_t size);
|
||||
void buf_free(buf_t *buf);
|
||||
void buf_clear(buf_t *buf);
|
||||
buf_t *buf_copy(const buf_t *buf);
|
||||
void buf_shrink(buf_t *buf);
|
||||
void buf_shrink_freelists(int free_all);
|
||||
void buf_dump_freelist_sizes(int severity);
|
||||
|
||||
size_t buf_datalen(const buf_t *buf);
|
||||
size_t buf_allocation(const buf_t *buf);
|
||||
size_t buf_slack(const buf_t *buf);
|
||||
|
||||
int read_to_buf(tor_socket_t s, size_t at_most, buf_t *buf, int *reached_eof,
|
||||
int *socket_error);
|
||||
int read_to_buf_tls(tor_tls_t *tls, size_t at_most, buf_t *buf);
|
||||
|
||||
int flush_buf(tor_socket_t s, buf_t *buf, size_t sz, size_t *buf_flushlen);
|
||||
int flush_buf_tls(tor_tls_t *tls, buf_t *buf, size_t sz, size_t *buf_flushlen);
|
||||
|
||||
int write_to_buf(const char *string, size_t string_len, buf_t *buf);
|
||||
int write_to_buf_zlib(buf_t *buf, tor_zlib_state_t *state,
|
||||
const char *data, size_t data_len, int done);
|
||||
int move_buf_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
|
||||
int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
|
||||
int fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto);
|
||||
int fetch_from_buf_http(buf_t *buf,
|
||||
char **headers_out, size_t max_headerlen,
|
||||
char **body_out, size_t *body_used, size_t max_bodylen,
|
||||
int force_complete);
|
||||
socks_request_t *socks_request_new(void);
|
||||
void socks_request_free(socks_request_t *req);
|
||||
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
||||
int log_sockstype, int safe_socks);
|
||||
int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason);
|
||||
int fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len);
|
||||
|
||||
int peek_buf_has_control0_command(buf_t *buf);
|
||||
|
||||
int fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out);
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
int fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
|
||||
int linkproto);
|
||||
int fetch_from_evbuffer_socks(struct evbuffer *buf, socks_request_t *req,
|
||||
int log_sockstype, int safe_socks);
|
||||
int fetch_from_evbuffer_socks_client(struct evbuffer *buf, int state,
|
||||
char **reason);
|
||||
int fetch_from_evbuffer_http(struct evbuffer *buf,
|
||||
char **headers_out, size_t max_headerlen,
|
||||
char **body_out, size_t *body_used, size_t max_bodylen,
|
||||
int force_complete);
|
||||
int peek_evbuffer_has_control0_command(struct evbuffer *buf);
|
||||
int write_to_evbuffer_zlib(struct evbuffer *buf, tor_zlib_state_t *state,
|
||||
const char *data, size_t data_len,
|
||||
int done);
|
||||
int fetch_ext_or_command_from_evbuffer(struct evbuffer *buf,
|
||||
ext_or_cmd_t **out);
|
||||
#endif
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
#define generic_buffer_new() evbuffer_new()
|
||||
#define generic_buffer_len(b) evbuffer_get_length((b))
|
||||
#define generic_buffer_add(b,dat,len) evbuffer_add((b),(dat),(len))
|
||||
#define generic_buffer_get(b,buf,buflen) evbuffer_remove((b),(buf),(buflen))
|
||||
#define generic_buffer_clear(b) evbuffer_drain((b), evbuffer_get_length((b)))
|
||||
#define generic_buffer_free(b) evbuffer_free((b))
|
||||
#define generic_buffer_fetch_ext_or_cmd(b, out) \
|
||||
fetch_ext_or_command_from_evbuffer((b), (out))
|
||||
#else
|
||||
#define generic_buffer_new() buf_new()
|
||||
#define generic_buffer_len(b) buf_datalen((b))
|
||||
#define generic_buffer_add(b,dat,len) write_to_buf((dat),(len),(b))
|
||||
#define generic_buffer_get(b,buf,buflen) fetch_from_buf((buf),(buflen),(b))
|
||||
#define generic_buffer_clear(b) buf_clear((b))
|
||||
#define generic_buffer_free(b) buf_free((b))
|
||||
#define generic_buffer_fetch_ext_or_cmd(b, out) \
|
||||
fetch_ext_or_command_from_buf((b), (out))
|
||||
#endif
|
||||
int generic_buffer_set_to_copy(generic_buffer_t **output,
|
||||
const generic_buffer_t *input);
|
||||
|
||||
void assert_buf_ok(buf_t *buf);
|
||||
|
||||
#ifdef BUFFERS_PRIVATE
|
||||
STATIC int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TOR_SRC_DIR="${TOR_SRC_DIR:-$ROOT_DIR/tor-src}"
|
||||
|
||||
if [[ ! -d "$TOR_SRC_DIR" ]]; then
|
||||
echo "Tor source tree not found at: $TOR_SRC_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$TOR_SRC_DIR"
|
||||
|
||||
if [[ ! -x "./configure" ]]; then
|
||||
echo "Running autogen.sh"
|
||||
./autogen.sh
|
||||
fi
|
||||
|
||||
echo "Configuring Tor static library build from: $TOR_SRC_DIR"
|
||||
./configure \
|
||||
--enable-static-tor \
|
||||
--disable-module-relay \
|
||||
--disable-module-dirauth \
|
||||
--disable-asciidoc \
|
||||
--disable-manpage \
|
||||
--disable-html-manual \
|
||||
--disable-unittests \
|
||||
--disable-tool-name-check \
|
||||
--with-libevent-dir="${LIBEVENT_DIR:-/mingw64}" \
|
||||
--with-openssl-dir="${OPENSSL_DIR:-/mingw64}" \
|
||||
--with-zlib-dir="${ZLIB_DIR:-/mingw64}"
|
||||
|
||||
echo "Building Tor"
|
||||
make -j"${NPROC:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)}"
|
||||
|
||||
echo
|
||||
echo "Build finished. Inspect these locations for static libraries:"
|
||||
echo " $TOR_SRC_DIR"
|
||||
echo " $TOR_SRC_DIR/src/lib"
|
||||
echo
|
||||
echo "Suggested next step for Triangles:"
|
||||
echo ' make -f src/makefile.unix USE_TOR_EMBEDDED=1 TOR_SOURCE_ROOT=src/tor/tor-src'
|
||||
-4191
File diff suppressed because it is too large
Load Diff
@@ -1,489 +0,0 @@
|
||||
/* * Copyright (c) 2012-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file channel.h
|
||||
* \brief Header file for channel.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CHANNEL_H
|
||||
#define TOR_CHANNEL_H
|
||||
|
||||
#include "or.h"
|
||||
#include "circuitmux.h"
|
||||
|
||||
/* Channel handler function pointer typedefs */
|
||||
typedef void (*channel_listener_fn_ptr)(channel_listener_t *, channel_t *);
|
||||
typedef void (*channel_cell_handler_fn_ptr)(channel_t *, cell_t *);
|
||||
typedef void (*channel_var_cell_handler_fn_ptr)(channel_t *, var_cell_t *);
|
||||
|
||||
struct cell_queue_entry_s;
|
||||
TOR_SIMPLEQ_HEAD(chan_cell_queue, cell_queue_entry_s) incoming_queue;
|
||||
typedef struct chan_cell_queue chan_cell_queue_t;
|
||||
|
||||
/*
|
||||
* Channel struct; see the channel_t typedef in or.h. A channel is an
|
||||
* abstract interface for the OR-to-OR connection, similar to connection_or_t,
|
||||
* but without the strong coupling to the underlying TLS implementation. They
|
||||
* are constructed by calling a protocol-specific function to open a channel
|
||||
* to a particular node, and once constructed support the abstract operations
|
||||
* defined below.
|
||||
*/
|
||||
|
||||
struct channel_s {
|
||||
/* Magic number for type-checking cast macros */
|
||||
uint32_t magic;
|
||||
|
||||
/* Current channel state */
|
||||
channel_state_t state;
|
||||
|
||||
/* Globally unique ID number for a channel over the lifetime of a Tor
|
||||
* process.
|
||||
*/
|
||||
uint64_t global_identifier;
|
||||
|
||||
/* Should we expect to see this channel in the channel lists? */
|
||||
unsigned char registered:1;
|
||||
|
||||
/** has this channel ever been open? */
|
||||
unsigned int has_been_open:1;
|
||||
|
||||
/** Why did we close?
|
||||
*/
|
||||
enum {
|
||||
CHANNEL_NOT_CLOSING = 0,
|
||||
CHANNEL_CLOSE_REQUESTED,
|
||||
CHANNEL_CLOSE_FROM_BELOW,
|
||||
CHANNEL_CLOSE_FOR_ERROR
|
||||
} reason_for_closing;
|
||||
|
||||
/* Timestamps for both cell channels and listeners */
|
||||
time_t timestamp_created; /* Channel created */
|
||||
time_t timestamp_active; /* Any activity */
|
||||
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/* Free a channel */
|
||||
void (*free)(channel_t *);
|
||||
/* Close an open channel */
|
||||
void (*close)(channel_t *);
|
||||
/* Describe the transport subclass for this channel */
|
||||
const char * (*describe_transport)(channel_t *);
|
||||
/* Optional method to dump transport-specific statistics on the channel */
|
||||
void (*dumpstats)(channel_t *, int);
|
||||
|
||||
/* Registered handlers for incoming cells */
|
||||
channel_cell_handler_fn_ptr cell_handler;
|
||||
channel_var_cell_handler_fn_ptr var_cell_handler;
|
||||
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/*
|
||||
* Ask the underlying transport what the remote endpoint address is, in
|
||||
* a tor_addr_t. This is optional and subclasses may leave this NULL.
|
||||
* If they implement it, they should write the address out to the
|
||||
* provided tor_addr_t *, and return 1 if successful or 0 if no address
|
||||
* available.
|
||||
*/
|
||||
int (*get_remote_addr)(channel_t *, tor_addr_t *);
|
||||
int (*get_transport_name)(channel_t *chan, char **transport_out);
|
||||
|
||||
#define GRD_FLAG_ORIGINAL 1
|
||||
#define GRD_FLAG_ADDR_ONLY 2
|
||||
/*
|
||||
* Get a text description of the remote endpoint; canonicalized if the flag
|
||||
* GRD_FLAG_ORIGINAL is not set, or the one we originally connected
|
||||
* to/received from if it is. If GRD_FLAG_ADDR_ONLY is set, we return only
|
||||
* the original address.
|
||||
*/
|
||||
const char * (*get_remote_descr)(channel_t *, int);
|
||||
/* Check if the lower layer has queued writes */
|
||||
int (*has_queued_writes)(channel_t *);
|
||||
/*
|
||||
* If the second param is zero, ask the lower layer if this is
|
||||
* 'canonical', for a transport-specific definition of canonical; if
|
||||
* it is 1, ask if the answer to the preceding query is safe to rely
|
||||
* on.
|
||||
*/
|
||||
int (*is_canonical)(channel_t *, int);
|
||||
/* Check if this channel matches a specified extend_info_t */
|
||||
int (*matches_extend_info)(channel_t *, extend_info_t *);
|
||||
/* Check if this channel matches a target address when extending */
|
||||
int (*matches_target)(channel_t *, const tor_addr_t *);
|
||||
/* Write a cell to an open channel */
|
||||
int (*write_cell)(channel_t *, cell_t *);
|
||||
/* Write a packed cell to an open channel */
|
||||
int (*write_packed_cell)(channel_t *, packed_cell_t *);
|
||||
/* Write a variable-length cell to an open channel */
|
||||
int (*write_var_cell)(channel_t *, var_cell_t *);
|
||||
|
||||
/*
|
||||
* Hash of the public RSA key for the other side's identity key, or
|
||||
* zeroes if the other side hasn't shown us a valid identity key.
|
||||
*/
|
||||
char identity_digest[DIGEST_LEN];
|
||||
/* Nickname of the OR on the other side, or NULL if none. */
|
||||
char *nickname;
|
||||
|
||||
/*
|
||||
* Linked list of channels with the same identity digest, for the
|
||||
* digest->channel map
|
||||
*/
|
||||
TOR_LIST_ENTRY(channel_s) next_with_same_id;
|
||||
|
||||
/* List of incoming cells to handle */
|
||||
chan_cell_queue_t incoming_queue;
|
||||
|
||||
/* List of queued outgoing cells */
|
||||
chan_cell_queue_t outgoing_queue;
|
||||
|
||||
/* Circuit mux for circuits sending on this channel */
|
||||
circuitmux_t *cmux;
|
||||
|
||||
/* Circuit ID generation stuff for use by circuitbuild.c */
|
||||
|
||||
/*
|
||||
* When we send CREATE cells along this connection, which half of the
|
||||
* space should we use?
|
||||
*/
|
||||
ENUM_BF(circ_id_type_t) circ_id_type:2;
|
||||
/** DOCDOC*/
|
||||
unsigned wide_circ_ids:1;
|
||||
/*
|
||||
* Which circ_id do we try to use next on this connection? This is
|
||||
* always in the range 0..1<<15-1.
|
||||
*/
|
||||
circid_t next_circ_id;
|
||||
|
||||
/* For how many circuits are we n_chan? What about p_chan? */
|
||||
unsigned int num_n_circuits, num_p_circuits;
|
||||
|
||||
/*
|
||||
* True iff this channel shouldn't get any new circs attached to it,
|
||||
* because the connection is too old, or because there's a better one.
|
||||
* More generally, this flag is used to note an unhealthy connection;
|
||||
* for example, if a bad connection fails we shouldn't assume that the
|
||||
* router itself has a problem.
|
||||
*/
|
||||
unsigned int is_bad_for_new_circs:1;
|
||||
|
||||
/** True iff we have decided that the other end of this connection
|
||||
* is a client. Channels with this flag set should never be used
|
||||
* to satisfy an EXTEND request. */
|
||||
unsigned int is_client:1;
|
||||
|
||||
/** Set if the channel was initiated remotely (came from a listener) */
|
||||
unsigned int is_incoming:1;
|
||||
|
||||
/** Set by lower layer if this is local; i.e., everything it communicates
|
||||
* with for this channel returns true for is_local_addr(). This is used
|
||||
* to decide whether to declare reachability when we receive something on
|
||||
* this channel in circuitbuild.c
|
||||
*/
|
||||
unsigned int is_local:1;
|
||||
|
||||
/** Channel timestamps for cell channels */
|
||||
time_t timestamp_client; /* Client used this, according to relay.c */
|
||||
time_t timestamp_drained; /* Output queue empty */
|
||||
time_t timestamp_recv; /* Cell received from lower layer */
|
||||
time_t timestamp_xmit; /* Cell sent to lower layer */
|
||||
|
||||
/* Timestamp for relay.c */
|
||||
time_t timestamp_last_added_nonpadding;
|
||||
|
||||
/** Unique ID for measuring direct network status requests;vtunneled ones
|
||||
* come over a circuit_t, which has a dirreq_id field as well, but is a
|
||||
* distinct namespace. */
|
||||
uint64_t dirreq_id;
|
||||
|
||||
/** Channel counters for cell channels */
|
||||
uint64_t n_cells_recved;
|
||||
uint64_t n_cells_xmitted;
|
||||
};
|
||||
|
||||
struct channel_listener_s {
|
||||
/* Current channel listener state */
|
||||
channel_listener_state_t state;
|
||||
|
||||
/* Globally unique ID number for a channel over the lifetime of a Tor
|
||||
* process.
|
||||
*/
|
||||
uint64_t global_identifier;
|
||||
|
||||
/* Should we expect to see this channel in the channel lists? */
|
||||
unsigned char registered:1;
|
||||
|
||||
/** Why did we close?
|
||||
*/
|
||||
enum {
|
||||
CHANNEL_LISTENER_NOT_CLOSING = 0,
|
||||
CHANNEL_LISTENER_CLOSE_REQUESTED,
|
||||
CHANNEL_LISTENER_CLOSE_FROM_BELOW,
|
||||
CHANNEL_LISTENER_CLOSE_FOR_ERROR
|
||||
} reason_for_closing;
|
||||
|
||||
/* Timestamps for both cell channels and listeners */
|
||||
time_t timestamp_created; /* Channel created */
|
||||
time_t timestamp_active; /* Any activity */
|
||||
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/* Free a channel */
|
||||
void (*free)(channel_listener_t *);
|
||||
/* Close an open channel */
|
||||
void (*close)(channel_listener_t *);
|
||||
/* Describe the transport subclass for this channel */
|
||||
const char * (*describe_transport)(channel_listener_t *);
|
||||
/* Optional method to dump transport-specific statistics on the channel */
|
||||
void (*dumpstats)(channel_listener_t *, int);
|
||||
|
||||
/* Registered listen handler to call on incoming connection */
|
||||
channel_listener_fn_ptr listener;
|
||||
|
||||
/* List of pending incoming connections */
|
||||
smartlist_t *incoming_list;
|
||||
|
||||
/* Timestamps for listeners */
|
||||
time_t timestamp_accepted;
|
||||
|
||||
/* Counters for listeners */
|
||||
uint64_t n_accepted;
|
||||
};
|
||||
|
||||
/* Channel state manipulations */
|
||||
|
||||
int channel_state_is_valid(channel_state_t state);
|
||||
int channel_listener_state_is_valid(channel_listener_state_t state);
|
||||
|
||||
int channel_state_can_transition(channel_state_t from, channel_state_t to);
|
||||
int channel_listener_state_can_transition(channel_listener_state_t from,
|
||||
channel_listener_state_t to);
|
||||
|
||||
const char * channel_state_to_string(channel_state_t state);
|
||||
const char *
|
||||
channel_listener_state_to_string(channel_listener_state_t state);
|
||||
|
||||
/* Abstract channel operations */
|
||||
|
||||
void channel_mark_for_close(channel_t *chan);
|
||||
void channel_write_cell(channel_t *chan, cell_t *cell);
|
||||
void channel_write_packed_cell(channel_t *chan, packed_cell_t *cell);
|
||||
void channel_write_var_cell(channel_t *chan, var_cell_t *cell);
|
||||
|
||||
void channel_listener_mark_for_close(channel_listener_t *chan_l);
|
||||
|
||||
/* Channel callback registrations */
|
||||
|
||||
/* Listener callback */
|
||||
channel_listener_fn_ptr
|
||||
channel_listener_get_listener_fn(channel_listener_t *chan);
|
||||
|
||||
void channel_listener_set_listener_fn(channel_listener_t *chan,
|
||||
channel_listener_fn_ptr listener);
|
||||
|
||||
/* Incoming cell callbacks */
|
||||
channel_cell_handler_fn_ptr channel_get_cell_handler(channel_t *chan);
|
||||
|
||||
channel_var_cell_handler_fn_ptr
|
||||
channel_get_var_cell_handler(channel_t *chan);
|
||||
|
||||
void channel_set_cell_handlers(channel_t *chan,
|
||||
channel_cell_handler_fn_ptr cell_handler,
|
||||
channel_var_cell_handler_fn_ptr
|
||||
var_cell_handler);
|
||||
|
||||
/* Clean up closed channels and channel listeners periodically; these are
|
||||
* called from run_scheduled_events() in onion_main.c.
|
||||
*/
|
||||
void channel_run_cleanup(void);
|
||||
void channel_listener_run_cleanup(void);
|
||||
|
||||
/* Close all channels and deallocate everything */
|
||||
void channel_free_all(void);
|
||||
|
||||
/* Dump some statistics in the log */
|
||||
void channel_dumpstats(int severity);
|
||||
void channel_listener_dumpstats(int severity);
|
||||
|
||||
/* Set the cmux policy on all active channels */
|
||||
void channel_set_cmux_policy_everywhere(circuitmux_policy_t *pol);
|
||||
|
||||
#ifdef TOR_CHANNEL_INTERNAL_
|
||||
|
||||
/* Channel operations for subclasses and internal use only */
|
||||
|
||||
/* Initialize a newly allocated channel - do this first in subclass
|
||||
* constructors.
|
||||
*/
|
||||
|
||||
void channel_init(channel_t *chan);
|
||||
void channel_init_listener(channel_listener_t *chan);
|
||||
|
||||
/* Channel registration/unregistration */
|
||||
void channel_register(channel_t *chan);
|
||||
void channel_unregister(channel_t *chan);
|
||||
|
||||
/* Channel listener registration/unregistration */
|
||||
void channel_listener_register(channel_listener_t *chan_l);
|
||||
void channel_listener_unregister(channel_listener_t *chan_l);
|
||||
|
||||
/* Close from below */
|
||||
void channel_close_from_lower_layer(channel_t *chan);
|
||||
void channel_close_for_error(channel_t *chan);
|
||||
void channel_closed(channel_t *chan);
|
||||
|
||||
void channel_listener_close_from_lower_layer(channel_listener_t *chan_l);
|
||||
void channel_listener_close_for_error(channel_listener_t *chan_l);
|
||||
void channel_listener_closed(channel_listener_t *chan_l);
|
||||
|
||||
/* Free a channel */
|
||||
void channel_free(channel_t *chan);
|
||||
void channel_listener_free(channel_listener_t *chan_l);
|
||||
|
||||
/* State/metadata setters */
|
||||
|
||||
void channel_change_state(channel_t *chan, channel_state_t to_state);
|
||||
void channel_clear_identity_digest(channel_t *chan);
|
||||
void channel_clear_remote_end(channel_t *chan);
|
||||
void channel_mark_local(channel_t *chan);
|
||||
void channel_mark_incoming(channel_t *chan);
|
||||
void channel_mark_outgoing(channel_t *chan);
|
||||
void channel_set_identity_digest(channel_t *chan,
|
||||
const char *identity_digest);
|
||||
void channel_set_remote_end(channel_t *chan,
|
||||
const char *identity_digest,
|
||||
const char *nickname);
|
||||
|
||||
void channel_listener_change_state(channel_listener_t *chan_l,
|
||||
channel_listener_state_t to_state);
|
||||
|
||||
/* Timestamp updates */
|
||||
void channel_timestamp_created(channel_t *chan);
|
||||
void channel_timestamp_active(channel_t *chan);
|
||||
void channel_timestamp_drained(channel_t *chan);
|
||||
void channel_timestamp_recv(channel_t *chan);
|
||||
void channel_timestamp_xmit(channel_t *chan);
|
||||
|
||||
void channel_listener_timestamp_created(channel_listener_t *chan_l);
|
||||
void channel_listener_timestamp_active(channel_listener_t *chan_l);
|
||||
void channel_listener_timestamp_accepted(channel_listener_t *chan_l);
|
||||
|
||||
/* Incoming channel handling */
|
||||
void channel_listener_process_incoming(channel_listener_t *listener);
|
||||
void channel_listener_queue_incoming(channel_listener_t *listener,
|
||||
channel_t *incoming);
|
||||
|
||||
/* Incoming cell handling */
|
||||
void channel_process_cells(channel_t *chan);
|
||||
void channel_queue_cell(channel_t *chan, cell_t *cell);
|
||||
void channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell);
|
||||
|
||||
/* Outgoing cell handling */
|
||||
void channel_flush_cells(channel_t *chan);
|
||||
|
||||
/* Request from lower layer for more cells if available */
|
||||
ssize_t channel_flush_some_cells(channel_t *chan, ssize_t num_cells);
|
||||
|
||||
/* Query if data available on this channel */
|
||||
int channel_more_to_flush(channel_t *chan);
|
||||
|
||||
/* Notify flushed outgoing for dirreq handling */
|
||||
void channel_notify_flushed(channel_t *chan);
|
||||
|
||||
/* Handle stuff we need to do on open like notifying circuits */
|
||||
void channel_do_open_actions(channel_t *chan);
|
||||
|
||||
#endif
|
||||
|
||||
/* Helper functions to perform operations on channels */
|
||||
|
||||
int channel_send_destroy(circid_t circ_id, channel_t *chan,
|
||||
int reason);
|
||||
|
||||
/*
|
||||
* Outside abstract interfaces that should eventually get turned into
|
||||
* something transport/address format independent.
|
||||
*/
|
||||
|
||||
channel_t * channel_connect(const tor_addr_t *addr, uint16_t port,
|
||||
const char *id_digest);
|
||||
|
||||
channel_t * channel_get_for_extend(const char *digest,
|
||||
const tor_addr_t *target_addr,
|
||||
const char **msg_out,
|
||||
int *launch_out);
|
||||
|
||||
/* Ask which of two channels is better for circuit-extension purposes */
|
||||
int channel_is_better(time_t now,
|
||||
channel_t *a, channel_t *b,
|
||||
int forgive_new_connections);
|
||||
|
||||
/** Channel lookups
|
||||
*/
|
||||
|
||||
channel_t * channel_find_by_global_id(uint64_t global_identifier);
|
||||
channel_t * channel_find_by_remote_digest(const char *identity_digest);
|
||||
|
||||
/** For things returned by channel_find_by_remote_digest(), walk the list.
|
||||
*/
|
||||
channel_t * channel_next_with_digest(channel_t *chan);
|
||||
|
||||
/*
|
||||
* Metadata queries/updates
|
||||
*/
|
||||
|
||||
const char * channel_describe_transport(channel_t *chan);
|
||||
void channel_dump_statistics(channel_t *chan, int severity);
|
||||
void channel_dump_transport_statistics(channel_t *chan, int severity);
|
||||
const char * channel_get_actual_remote_descr(channel_t *chan);
|
||||
const char * channel_get_actual_remote_address(channel_t *chan);
|
||||
int channel_get_addr_if_possible(channel_t *chan, tor_addr_t *addr_out);
|
||||
const char * channel_get_canonical_remote_descr(channel_t *chan);
|
||||
int channel_has_queued_writes(channel_t *chan);
|
||||
int channel_is_bad_for_new_circs(channel_t *chan);
|
||||
void channel_mark_bad_for_new_circs(channel_t *chan);
|
||||
int channel_is_canonical(channel_t *chan);
|
||||
int channel_is_canonical_is_reliable(channel_t *chan);
|
||||
int channel_is_client(channel_t *chan);
|
||||
int channel_is_local(channel_t *chan);
|
||||
int channel_is_incoming(channel_t *chan);
|
||||
int channel_is_outgoing(channel_t *chan);
|
||||
void channel_mark_client(channel_t *chan);
|
||||
int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info);
|
||||
int channel_matches_target_addr_for_extend(channel_t *chan,
|
||||
const tor_addr_t *target);
|
||||
unsigned int channel_num_circuits(channel_t *chan);
|
||||
void channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd,
|
||||
int consider_identity);
|
||||
void channel_timestamp_client(channel_t *chan);
|
||||
|
||||
const char * channel_listener_describe_transport(channel_listener_t *chan_l);
|
||||
void channel_listener_dump_statistics(channel_listener_t *chan_l,
|
||||
int severity);
|
||||
void channel_listener_dump_transport_statistics(channel_listener_t *chan_l,
|
||||
int severity);
|
||||
|
||||
/* Timestamp queries */
|
||||
time_t channel_when_created(channel_t *chan);
|
||||
time_t channel_when_last_active(channel_t *chan);
|
||||
time_t channel_when_last_client(channel_t *chan);
|
||||
time_t channel_when_last_drained(channel_t *chan);
|
||||
time_t channel_when_last_recv(channel_t *chan);
|
||||
time_t channel_when_last_xmit(channel_t *chan);
|
||||
|
||||
time_t channel_listener_when_created(channel_listener_t *chan_l);
|
||||
time_t channel_listener_when_last_active(channel_listener_t *chan_l);
|
||||
time_t channel_listener_when_last_accepted(channel_listener_t *chan_l);
|
||||
|
||||
/* Counter queries */
|
||||
uint64_t channel_count_recved(channel_t *chan);
|
||||
uint64_t channel_count_xmitted(channel_t *chan);
|
||||
|
||||
uint64_t channel_listener_count_accepted(channel_listener_t *chan_l);
|
||||
|
||||
int packed_cell_is_destroy(channel_t *chan,
|
||||
const packed_cell_t *packed_cell,
|
||||
circid_t *circid_out);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +0,0 @@
|
||||
/* * Copyright (c) 2012-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file channeltls.h
|
||||
* \brief Header file for channeltls.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CHANNELTLS_H
|
||||
#define TOR_CHANNELTLS_H
|
||||
|
||||
#include "or.h"
|
||||
#include "channel.h"
|
||||
|
||||
#define BASE_CHAN_TO_TLS(c) (channel_tls_from_base((c)))
|
||||
#define TLS_CHAN_TO_BASE(c) (channel_tls_to_base((c)))
|
||||
|
||||
#define TLS_CHAN_MAGIC 0x8a192427U
|
||||
|
||||
#ifdef TOR_CHANNEL_INTERNAL_
|
||||
|
||||
struct channel_tls_s {
|
||||
/* Base channel_t struct */
|
||||
channel_t base_;
|
||||
/* or_connection_t pointer */
|
||||
or_connection_t *conn;
|
||||
};
|
||||
|
||||
#endif /* TOR_CHANNEL_INTERNAL_ */
|
||||
|
||||
channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
|
||||
const char *id_digest);
|
||||
channel_listener_t * channel_tls_get_listener(void);
|
||||
channel_listener_t * channel_tls_start_listener(void);
|
||||
channel_t * channel_tls_handle_incoming(or_connection_t *orconn);
|
||||
|
||||
/* Casts */
|
||||
|
||||
channel_t * channel_tls_to_base(channel_tls_t *tlschan);
|
||||
channel_tls_t * channel_tls_from_base(channel_t *chan);
|
||||
|
||||
/* Things for connection_or.c to call back into */
|
||||
ssize_t channel_tls_flush_some_cells(channel_tls_t *chan, ssize_t num_cells);
|
||||
int channel_tls_more_to_flush(channel_tls_t *chan);
|
||||
void channel_tls_handle_cell(cell_t *cell, or_connection_t *conn);
|
||||
void channel_tls_handle_state_change_on_orconn(channel_tls_t *chan,
|
||||
or_connection_t *conn,
|
||||
uint8_t old_state,
|
||||
uint8_t state);
|
||||
void channel_tls_handle_var_cell(var_cell_t *var_cell,
|
||||
or_connection_t *conn);
|
||||
|
||||
/* Cleanup at shutdown */
|
||||
void channel_tls_free_all(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
/* This is an include file used to define the list of ciphers clients should
|
||||
* advertise. Before including it, you should define the CIPHER and XCIPHER
|
||||
* macros.
|
||||
*
|
||||
* This file was automatically generated by get_mozilla_ciphers.py.
|
||||
*/
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc00a, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00a, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc014, TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc014, TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||
CIPHER(0x0088, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0088, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
|
||||
CIPHER(0x0087, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0087, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_AES_256_SHA
|
||||
CIPHER(0x0039, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0039, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_AES_256_SHA
|
||||
CIPHER(0x0038, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0038, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc00f, TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00f, TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
||||
CIPHER(0xc005, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc005, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||
CIPHER(0x0084, TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0084, TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_AES_256_SHA
|
||||
CIPHER(0x0035, TLS1_TXT_RSA_WITH_AES_256_SHA)
|
||||
#else
|
||||
XCIPHER(0x0035, TLS1_TXT_RSA_WITH_AES_256_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc007, TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc007, TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc009, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc009, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc011, TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc011, TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc013, TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc013, TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||
CIPHER(0x0045, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0045, TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
|
||||
CIPHER(0x0044, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0044, TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_RSA_WITH_AES_128_SHA
|
||||
CIPHER(0x0033, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0033, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_DHE_DSS_WITH_AES_128_SHA
|
||||
CIPHER(0x0032, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0032, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc00c, TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00c, TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc00e, TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00e, TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA
|
||||
CIPHER(0xc002, TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0xc002, TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA
|
||||
CIPHER(0xc004, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xc004, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_SEED_SHA
|
||||
CIPHER(0x0096, TLS1_TXT_RSA_WITH_SEED_SHA)
|
||||
#else
|
||||
XCIPHER(0x0096, TLS1_TXT_RSA_WITH_SEED_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||
CIPHER(0x0041, TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0x0041, TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_RC4_128_MD5
|
||||
CIPHER(0x0004, SSL3_TXT_RSA_RC4_128_MD5)
|
||||
#else
|
||||
XCIPHER(0x0004, SSL3_TXT_RSA_RC4_128_MD5)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_RC4_128_SHA
|
||||
CIPHER(0x0005, SSL3_TXT_RSA_RC4_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x0005, SSL3_TXT_RSA_RC4_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_RSA_WITH_AES_128_SHA
|
||||
CIPHER(0x002f, TLS1_TXT_RSA_WITH_AES_128_SHA)
|
||||
#else
|
||||
XCIPHER(0x002f, TLS1_TXT_RSA_WITH_AES_128_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc008, TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc008, TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc012, TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc012, TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA
|
||||
CIPHER(0x0016, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x0016, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA
|
||||
CIPHER(0x0013, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x0013, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc00d, TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc00d, TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
#ifdef TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA
|
||||
CIPHER(0xc003, TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0xc003, TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
/* No openssl macro found for 0xfeff */
|
||||
#ifdef SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
|
||||
CIPHER(0xfeff, SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA)
|
||||
#else
|
||||
XCIPHER(0xfeff, SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA)
|
||||
#endif
|
||||
#ifdef SSL3_TXT_RSA_DES_192_CBC3_SHA
|
||||
CIPHER(0x000a, SSL3_TXT_RSA_DES_192_CBC3_SHA)
|
||||
#else
|
||||
XCIPHER(0x000a, SSL3_TXT_RSA_DES_192_CBC3_SHA)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitbuild.h
|
||||
* \brief Header file for circuitbuild.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCPATHBIAS_H
|
||||
#define TOR_CIRCPATHBIAS_H
|
||||
|
||||
double pathbias_get_extreme_rate(const or_options_t *options);
|
||||
double pathbias_get_extreme_use_rate(const or_options_t *options);
|
||||
int pathbias_get_dropguards(const or_options_t *options);
|
||||
void pathbias_count_timeout(origin_circuit_t *circ);
|
||||
void pathbias_count_build_success(origin_circuit_t *circ);
|
||||
int pathbias_count_build_attempt(origin_circuit_t *circ);
|
||||
int pathbias_check_close(origin_circuit_t *circ, int reason);
|
||||
int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
|
||||
void pathbias_count_use_attempt(origin_circuit_t *circ);
|
||||
void pathbias_mark_use_success(origin_circuit_t *circ);
|
||||
void pathbias_mark_use_rollback(origin_circuit_t *circ);
|
||||
const char *pathbias_state_to_string(path_state_t state);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitbuild.h
|
||||
* \brief Header file for circuitbuild.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITBUILD_H
|
||||
#define TOR_CIRCUITBUILD_H
|
||||
|
||||
char *circuit_list_path(origin_circuit_t *circ, int verbose);
|
||||
char *circuit_list_path_for_controller(origin_circuit_t *circ);
|
||||
void circuit_log_path(int severity, unsigned int domain,
|
||||
origin_circuit_t *circ);
|
||||
void circuit_rep_hist_note_result(origin_circuit_t *circ);
|
||||
origin_circuit_t *origin_circuit_init(uint8_t purpose, int flags);
|
||||
origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
|
||||
extend_info_t *exit,
|
||||
int flags);
|
||||
int circuit_handle_first_hop(origin_circuit_t *circ);
|
||||
void circuit_n_chan_done(channel_t *chan, int status);
|
||||
int inform_testing_reachability(void);
|
||||
int circuit_timeout_want_to_count_circ(origin_circuit_t *circ);
|
||||
int circuit_send_next_onion_skin(origin_circuit_t *circ);
|
||||
void circuit_note_clock_jumped(int seconds_elapsed);
|
||||
int circuit_extend(cell_t *cell, circuit_t *circ);
|
||||
int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data,
|
||||
int reverse);
|
||||
struct created_cell_t;
|
||||
int circuit_finish_handshake(origin_circuit_t *circ,
|
||||
const struct created_cell_t *created_cell);
|
||||
int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer,
|
||||
int reason);
|
||||
int onionskin_answer(or_circuit_t *circ,
|
||||
const struct created_cell_t *created_cell,
|
||||
const char *keys,
|
||||
const uint8_t *rend_circ_nonce);
|
||||
int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
|
||||
int *need_capacity);
|
||||
|
||||
int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info);
|
||||
int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
|
||||
void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
|
||||
extend_info_t *extend_info_new(const char *nickname, const char *digest,
|
||||
crypto_pk_t *onion_key,
|
||||
const curve25519_public_key_t *curve25519_key,
|
||||
const tor_addr_t *addr, uint16_t port);
|
||||
extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
|
||||
extend_info_t *extend_info_dup(extend_info_t *info);
|
||||
void extend_info_free(extend_info_t *info);
|
||||
const node_t *build_state_get_exit_node(cpath_build_state_t *state);
|
||||
const char *build_state_get_exit_nickname(cpath_build_state_t *state);
|
||||
|
||||
const node_t *choose_good_entry_server(uint8_t purpose,
|
||||
cpath_build_state_t *state);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitlist.h
|
||||
* \brief Header file for circuitlist.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITLIST_H
|
||||
#define TOR_CIRCUITLIST_H
|
||||
|
||||
#include "testsupport.h"
|
||||
|
||||
TOR_LIST_HEAD(global_circuitlist_s, circuit_t);
|
||||
|
||||
struct global_circuitlist_s* circuit_get_global_list(void);
|
||||
const char *circuit_state_to_string(int state);
|
||||
const char *circuit_purpose_to_controller_string(uint8_t purpose);
|
||||
const char *circuit_purpose_to_controller_hs_state_string(uint8_t purpose);
|
||||
const char *circuit_purpose_to_string(uint8_t purpose);
|
||||
void circuit_dump_by_conn(connection_t *conn, int severity);
|
||||
void circuit_dump_by_chan(channel_t *chan, int severity);
|
||||
void circuit_set_p_circid_chan(or_circuit_t *circ, circid_t id,
|
||||
channel_t *chan);
|
||||
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id,
|
||||
channel_t *chan);
|
||||
void channel_mark_circid_unusable(channel_t *chan, circid_t id);
|
||||
void channel_mark_circid_usable(channel_t *chan, circid_t id);
|
||||
void circuit_set_state(circuit_t *circ, uint8_t state);
|
||||
void circuit_close_all_marked(void);
|
||||
int32_t circuit_initial_package_window(void);
|
||||
origin_circuit_t *origin_circuit_new(void);
|
||||
or_circuit_t *or_circuit_new(circid_t p_circ_id, channel_t *p_chan);
|
||||
circuit_t *circuit_get_by_circid_channel(circid_t circ_id,
|
||||
channel_t *chan);
|
||||
circuit_t *
|
||||
circuit_get_by_circid_channel_even_if_marked(circid_t circ_id,
|
||||
channel_t *chan);
|
||||
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan);
|
||||
circuit_t *circuit_get_by_edge_conn(edge_connection_t *conn);
|
||||
void circuit_unlink_all_from_channel(channel_t *chan, int reason);
|
||||
origin_circuit_t *circuit_get_by_global_id(uint32_t id);
|
||||
origin_circuit_t *circuit_get_ready_rend_circ_by_rend_data(
|
||||
const rend_data_t *rend_data);
|
||||
origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
|
||||
const char *digest, uint8_t purpose);
|
||||
or_circuit_t *circuit_get_rendezvous(const char *cookie);
|
||||
or_circuit_t *circuit_get_intro_point(const char *digest);
|
||||
origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
|
||||
extend_info_t *info, int flags);
|
||||
void circuit_mark_all_unused_circs(void);
|
||||
void circuit_mark_all_dirty_circs_as_unusable(void);
|
||||
void circuit_mark_for_close_(circuit_t *circ, int reason,
|
||||
int line, const char *file);
|
||||
int circuit_get_cpath_len(origin_circuit_t *circ);
|
||||
void circuit_clear_cpath(origin_circuit_t *circ);
|
||||
crypt_path_t *circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum);
|
||||
void circuit_get_all_pending_on_channel(smartlist_t *out,
|
||||
channel_t *chan);
|
||||
int circuit_count_pending_on_channel(channel_t *chan);
|
||||
|
||||
#define circuit_mark_for_close(c, reason) \
|
||||
circuit_mark_for_close_((c), (reason), __LINE__, SHORT_FILE__)
|
||||
|
||||
void assert_cpath_layer_ok(const crypt_path_t *cp);
|
||||
void assert_circuit_ok(const circuit_t *c);
|
||||
void circuit_free_all(void);
|
||||
void circuits_handle_oom(size_t current_allocation);
|
||||
|
||||
void channel_note_destroy_pending(channel_t *chan, circid_t id);
|
||||
void channel_note_destroy_not_pending(channel_t *chan, circid_t id);
|
||||
|
||||
#ifdef CIRCUITLIST_PRIVATE
|
||||
STATIC void circuit_free(circuit_t *circ);
|
||||
STATIC size_t n_cells_in_circ_queues(const circuit_t *c);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,147 +0,0 @@
|
||||
/* * Copyright (c) 2012-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitmux.h
|
||||
* \brief Header file for circuitmux.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITMUX_H
|
||||
#define TOR_CIRCUITMUX_H
|
||||
|
||||
#include "or.h"
|
||||
#include "testsupport.h"
|
||||
|
||||
typedef struct circuitmux_policy_s circuitmux_policy_t;
|
||||
typedef struct circuitmux_policy_data_s circuitmux_policy_data_t;
|
||||
typedef struct circuitmux_policy_circ_data_s circuitmux_policy_circ_data_t;
|
||||
|
||||
struct circuitmux_policy_s {
|
||||
/* Allocate cmux-wide policy-specific data */
|
||||
circuitmux_policy_data_t * (*alloc_cmux_data)(circuitmux_t *cmux);
|
||||
/* Free cmux-wide policy-specific data */
|
||||
void (*free_cmux_data)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
/* Allocate circuit policy-specific data for a newly attached circuit */
|
||||
circuitmux_policy_circ_data_t *
|
||||
(*alloc_circ_data)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
cell_direction_t direction,
|
||||
unsigned int cell_count);
|
||||
/* Free circuit policy-specific data */
|
||||
void (*free_circ_data)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
/* Notify that a circuit has become active/inactive */
|
||||
void (*notify_circ_active)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
void (*notify_circ_inactive)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
/* Notify of arriving/transmitted cells on a circuit */
|
||||
void (*notify_set_n_cells)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data,
|
||||
unsigned int n_cells);
|
||||
void (*notify_xmit_cells)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data,
|
||||
unsigned int n_cells);
|
||||
/* Choose a circuit */
|
||||
circuit_t * (*pick_active_circuit)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
};
|
||||
|
||||
/*
|
||||
* Circuitmux policy implementations can subclass this to store circuitmux-
|
||||
* wide data; it just has the magic number in the base struct.
|
||||
*/
|
||||
|
||||
struct circuitmux_policy_data_s {
|
||||
uint32_t magic;
|
||||
};
|
||||
|
||||
/*
|
||||
* Circuitmux policy implementations can subclass this to store circuit-
|
||||
* specific data; it just has the magic number in the base struct.
|
||||
*/
|
||||
|
||||
struct circuitmux_policy_circ_data_s {
|
||||
uint32_t magic;
|
||||
};
|
||||
|
||||
/*
|
||||
* Upcast #defines for the above types
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert a circuitmux_policy_data_t subtype to a circuitmux_policy_data_t.
|
||||
*/
|
||||
|
||||
#define TO_CMUX_POL_DATA(x) (&((x)->base_))
|
||||
|
||||
/**
|
||||
* Convert a circuitmux_policy_circ_data_t subtype to a
|
||||
* circuitmux_policy_circ_data_t.
|
||||
*/
|
||||
|
||||
#define TO_CMUX_POL_CIRC_DATA(x) (&((x)->base_))
|
||||
|
||||
/* Consistency check */
|
||||
void circuitmux_assert_okay(circuitmux_t *cmux);
|
||||
|
||||
/* Create/destroy */
|
||||
circuitmux_t * circuitmux_alloc(void);
|
||||
void circuitmux_detach_all_circuits(circuitmux_t *cmux);
|
||||
void circuitmux_free(circuitmux_t *cmux);
|
||||
|
||||
/* Policy control */
|
||||
void circuitmux_clear_policy(circuitmux_t *cmux);
|
||||
const circuitmux_policy_t * circuitmux_get_policy(circuitmux_t *cmux);
|
||||
void circuitmux_set_policy(circuitmux_t *cmux,
|
||||
const circuitmux_policy_t *pol);
|
||||
|
||||
/* Status inquiries */
|
||||
cell_direction_t circuitmux_attached_circuit_direction(
|
||||
circuitmux_t *cmux,
|
||||
circuit_t *circ);
|
||||
int circuitmux_is_circuit_attached(circuitmux_t *cmux, circuit_t *circ);
|
||||
int circuitmux_is_circuit_active(circuitmux_t *cmux, circuit_t *circ);
|
||||
unsigned int circuitmux_num_cells_for_circuit(circuitmux_t *cmux,
|
||||
circuit_t *circ);
|
||||
unsigned int circuitmux_num_cells(circuitmux_t *cmux);
|
||||
unsigned int circuitmux_num_circuits(circuitmux_t *cmux);
|
||||
unsigned int circuitmux_num_active_circuits(circuitmux_t *cmux);
|
||||
|
||||
/* Channel interface */
|
||||
circuit_t * circuitmux_get_first_active_circuit(circuitmux_t *cmux,
|
||||
cell_queue_t **destroy_queue_out);
|
||||
void circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
|
||||
unsigned int n_cells);
|
||||
void circuitmux_notify_xmit_destroy(circuitmux_t *cmux);
|
||||
|
||||
/* Circuit interface */
|
||||
MOCK_DECL(void, circuitmux_attach_circuit, (circuitmux_t *cmux,
|
||||
circuit_t *circ,
|
||||
cell_direction_t direction));
|
||||
MOCK_DECL(void, circuitmux_detach_circuit,
|
||||
(circuitmux_t *cmux, circuit_t *circ));
|
||||
void circuitmux_clear_num_cells(circuitmux_t *cmux, circuit_t *circ);
|
||||
void circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
|
||||
unsigned int n_cells);
|
||||
|
||||
void circuitmux_append_destroy_cell(channel_t *chan,
|
||||
circuitmux_t *cmux, circid_t circ_id,
|
||||
uint8_t reason);
|
||||
void circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux,
|
||||
channel_t *chan);
|
||||
|
||||
#endif /* TOR_CIRCUITMUX_H */
|
||||
|
||||
@@ -1,684 +0,0 @@
|
||||
/* * Copyright (c) 2012-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitmux_ewma.c
|
||||
* \brief EWMA circuit selection as a circuitmux_t policy
|
||||
**/
|
||||
|
||||
#define TOR_CIRCUITMUX_EWMA_C_
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "or.h"
|
||||
#include "circuitmux.h"
|
||||
#include "circuitmux_ewma.h"
|
||||
#include "networkstatus.h"
|
||||
|
||||
/*** EWMA parameter #defines ***/
|
||||
|
||||
/** How long does a tick last (seconds)? */
|
||||
#define EWMA_TICK_LEN 10
|
||||
|
||||
/** The default per-tick scale factor, if it hasn't been overridden by a
|
||||
* consensus or a configuration setting. zero means "disabled". */
|
||||
#define EWMA_DEFAULT_HALFLIFE 0.0
|
||||
|
||||
/*** Some useful constant #defines ***/
|
||||
|
||||
/*DOCDOC*/
|
||||
#define EPSILON 0.00001
|
||||
/*DOCDOC*/
|
||||
#define LOG_ONEHALF -0.69314718055994529
|
||||
|
||||
/*** EWMA structures ***/
|
||||
|
||||
typedef struct cell_ewma_s cell_ewma_t;
|
||||
typedef struct ewma_policy_data_s ewma_policy_data_t;
|
||||
typedef struct ewma_policy_circ_data_s ewma_policy_circ_data_t;
|
||||
|
||||
/**
|
||||
* The cell_ewma_t structure keeps track of how many cells a circuit has
|
||||
* transferred recently. It keeps an EWMA (exponentially weighted moving
|
||||
* average) of the number of cells flushed from the circuit queue onto a
|
||||
* connection in channel_flush_from_first_active_circuit().
|
||||
*/
|
||||
|
||||
struct cell_ewma_s {
|
||||
/** The last 'tick' at which we recalibrated cell_count.
|
||||
*
|
||||
* A cell sent at exactly the start of this tick has weight 1.0. Cells sent
|
||||
* since the start of this tick have weight greater than 1.0; ones sent
|
||||
* earlier have less weight. */
|
||||
unsigned int last_adjusted_tick;
|
||||
/** The EWMA of the cell count. */
|
||||
double cell_count;
|
||||
/** True iff this is the cell count for a circuit's previous
|
||||
* channel. */
|
||||
unsigned int is_for_p_chan : 1;
|
||||
/** The position of the circuit within the OR connection's priority
|
||||
* queue. */
|
||||
int heap_index;
|
||||
};
|
||||
|
||||
struct ewma_policy_data_s {
|
||||
circuitmux_policy_data_t base_;
|
||||
|
||||
/**
|
||||
* Priority queue of cell_ewma_t for circuits with queued cells waiting
|
||||
* for room to free up on the channel that owns this circuitmux. Kept
|
||||
* in heap order according to EWMA. This was formerly in channel_t, and
|
||||
* in or_connection_t before that.
|
||||
*/
|
||||
smartlist_t *active_circuit_pqueue;
|
||||
|
||||
/**
|
||||
* The tick on which the cell_ewma_ts in active_circuit_pqueue last had
|
||||
* their ewma values rescaled. This was formerly in channel_t, and in
|
||||
* or_connection_t before that.
|
||||
*/
|
||||
unsigned int active_circuit_pqueue_last_recalibrated;
|
||||
};
|
||||
|
||||
struct ewma_policy_circ_data_s {
|
||||
circuitmux_policy_circ_data_t base_;
|
||||
|
||||
/**
|
||||
* The EWMA count for the number of cells flushed from this circuit
|
||||
* onto this circuitmux. Used to determine which circuit to flush
|
||||
* from next. This was formerly in circuit_t and or_circuit_t.
|
||||
*/
|
||||
cell_ewma_t cell_ewma;
|
||||
|
||||
/**
|
||||
* Pointer back to the circuit_t this is for; since we're separating
|
||||
* out circuit selection policy like this, we can't attach cell_ewma_t
|
||||
* to the circuit_t any more, so we can't use SUBTYPE_P directly to a
|
||||
* circuit_t like before; instead get it here.
|
||||
*/
|
||||
circuit_t *circ;
|
||||
};
|
||||
|
||||
#define EWMA_POL_DATA_MAGIC 0x2fd8b16aU
|
||||
#define EWMA_POL_CIRC_DATA_MAGIC 0x761e7747U
|
||||
|
||||
/*** Downcasts for the above types ***/
|
||||
|
||||
static ewma_policy_data_t *
|
||||
TO_EWMA_POL_DATA(circuitmux_policy_data_t *);
|
||||
|
||||
static ewma_policy_circ_data_t *
|
||||
TO_EWMA_POL_CIRC_DATA(circuitmux_policy_circ_data_t *);
|
||||
|
||||
/**
|
||||
* Downcast a circuitmux_policy_data_t to an ewma_policy_data_t and assert
|
||||
* if the cast is impossible.
|
||||
*/
|
||||
|
||||
static INLINE ewma_policy_data_t *
|
||||
TO_EWMA_POL_DATA(circuitmux_policy_data_t *pol)
|
||||
{
|
||||
if (!pol) return NULL;
|
||||
else {
|
||||
tor_assert(pol->magic == EWMA_POL_DATA_MAGIC);
|
||||
return DOWNCAST(ewma_policy_data_t, pol);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downcast a circuitmux_policy_circ_data_t to an ewma_policy_circ_data_t
|
||||
* and assert if the cast is impossible.
|
||||
*/
|
||||
|
||||
static INLINE ewma_policy_circ_data_t *
|
||||
TO_EWMA_POL_CIRC_DATA(circuitmux_policy_circ_data_t *pol)
|
||||
{
|
||||
if (!pol) return NULL;
|
||||
else {
|
||||
tor_assert(pol->magic == EWMA_POL_CIRC_DATA_MAGIC);
|
||||
return DOWNCAST(ewma_policy_circ_data_t, pol);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Static declarations for circuitmux_ewma.c ***/
|
||||
|
||||
static void add_cell_ewma(ewma_policy_data_t *pol, cell_ewma_t *ewma);
|
||||
static int compare_cell_ewma_counts(const void *p1, const void *p2);
|
||||
static unsigned cell_ewma_tick_from_timeval(const struct timeval *now,
|
||||
double *remainder_out);
|
||||
static circuit_t * cell_ewma_to_circuit(cell_ewma_t *ewma);
|
||||
static INLINE double get_scale_factor(unsigned from_tick, unsigned to_tick);
|
||||
static cell_ewma_t * pop_first_cell_ewma(ewma_policy_data_t *pol);
|
||||
static void remove_cell_ewma(ewma_policy_data_t *pol, cell_ewma_t *ewma);
|
||||
static void scale_single_cell_ewma(cell_ewma_t *ewma, unsigned cur_tick);
|
||||
static void scale_active_circuits(ewma_policy_data_t *pol,
|
||||
unsigned cur_tick);
|
||||
|
||||
/*** Circuitmux policy methods ***/
|
||||
|
||||
static circuitmux_policy_data_t * ewma_alloc_cmux_data(circuitmux_t *cmux);
|
||||
static void ewma_free_cmux_data(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
static circuitmux_policy_circ_data_t *
|
||||
ewma_alloc_circ_data(circuitmux_t *cmux, circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ, cell_direction_t direction,
|
||||
unsigned int cell_count);
|
||||
static void
|
||||
ewma_free_circ_data(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
static void
|
||||
ewma_notify_circ_active(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
static void
|
||||
ewma_notify_circ_inactive(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data);
|
||||
static void
|
||||
ewma_notify_xmit_cells(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data,
|
||||
unsigned int n_cells);
|
||||
static circuit_t *
|
||||
ewma_pick_active_circuit(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
|
||||
/*** EWMA global variables ***/
|
||||
|
||||
/** The per-tick scale factor to be used when computing cell-count EWMA
|
||||
* values. (A cell sent N ticks before the start of the current tick
|
||||
* has value ewma_scale_factor ** N.)
|
||||
*/
|
||||
static double ewma_scale_factor = 0.1;
|
||||
/* DOCDOC ewma_enabled */
|
||||
static int ewma_enabled = 0;
|
||||
|
||||
/*** EWMA circuitmux_policy_t method table ***/
|
||||
|
||||
circuitmux_policy_t ewma_policy = {
|
||||
/*.alloc_cmux_data =*/ ewma_alloc_cmux_data,
|
||||
/*.free_cmux_data =*/ ewma_free_cmux_data,
|
||||
/*.alloc_circ_data =*/ ewma_alloc_circ_data,
|
||||
/*.free_circ_data =*/ ewma_free_circ_data,
|
||||
/*.notify_circ_active =*/ ewma_notify_circ_active,
|
||||
/*.notify_circ_inactive =*/ ewma_notify_circ_inactive,
|
||||
/*.notify_set_n_cells =*/ NULL, /* EWMA doesn't need this */
|
||||
/*.notify_xmit_cells =*/ ewma_notify_xmit_cells,
|
||||
/*.pick_active_circuit =*/ ewma_pick_active_circuit
|
||||
};
|
||||
|
||||
/*** EWMA method implementations using the below EWMA helper functions ***/
|
||||
|
||||
/**
|
||||
* Allocate an ewma_policy_data_t and upcast it to a circuitmux_policy_data_t;
|
||||
* this is called when setting the policy on a circuitmux_t to ewma_policy.
|
||||
*/
|
||||
|
||||
static circuitmux_policy_data_t *
|
||||
ewma_alloc_cmux_data(circuitmux_t *cmux)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
|
||||
pol = tor_malloc_zero(sizeof(*pol));
|
||||
pol->base_.magic = EWMA_POL_DATA_MAGIC;
|
||||
pol->active_circuit_pqueue = smartlist_new();
|
||||
pol->active_circuit_pqueue_last_recalibrated = cell_ewma_get_tick();
|
||||
|
||||
return TO_CMUX_POL_DATA(pol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an ewma_policy_data_t allocated with ewma_alloc_cmux_data()
|
||||
*/
|
||||
|
||||
static void
|
||||
ewma_free_cmux_data(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
if (!pol_data) return;
|
||||
|
||||
pol = TO_EWMA_POL_DATA(pol_data);
|
||||
|
||||
smartlist_free(pol->active_circuit_pqueue);
|
||||
tor_free(pol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate an ewma_policy_circ_data_t and upcast it to a
|
||||
* circuitmux_policy_data_t; this is called when attaching a circuit to a
|
||||
* circuitmux_t with ewma_policy.
|
||||
*/
|
||||
|
||||
static circuitmux_policy_circ_data_t *
|
||||
ewma_alloc_circ_data(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
cell_direction_t direction,
|
||||
unsigned int cell_count)
|
||||
{
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(pol_data);
|
||||
tor_assert(circ);
|
||||
tor_assert(direction == CELL_DIRECTION_OUT ||
|
||||
direction == CELL_DIRECTION_IN);
|
||||
/* Shut the compiler up */
|
||||
tor_assert(cell_count == cell_count);
|
||||
|
||||
cdata = tor_malloc_zero(sizeof(*cdata));
|
||||
cdata->base_.magic = EWMA_POL_CIRC_DATA_MAGIC;
|
||||
cdata->circ = circ;
|
||||
|
||||
/*
|
||||
* Initialize the cell_ewma_t structure (formerly in
|
||||
* init_circuit_base())
|
||||
*/
|
||||
cdata->cell_ewma.last_adjusted_tick = cell_ewma_get_tick();
|
||||
cdata->cell_ewma.cell_count = 0.0;
|
||||
cdata->cell_ewma.heap_index = -1;
|
||||
if (direction == CELL_DIRECTION_IN) {
|
||||
cdata->cell_ewma.is_for_p_chan = 1;
|
||||
} else {
|
||||
cdata->cell_ewma.is_for_p_chan = 0;
|
||||
}
|
||||
|
||||
return TO_CMUX_POL_CIRC_DATA(cdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an ewma_policy_circ_data_t allocated with ewma_alloc_circ_data()
|
||||
*/
|
||||
|
||||
static void
|
||||
ewma_free_circ_data(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data)
|
||||
|
||||
{
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(circ);
|
||||
tor_assert(pol_data);
|
||||
|
||||
if (!pol_circ_data) return;
|
||||
|
||||
cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data);
|
||||
|
||||
tor_free(cdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle circuit activation; this inserts the circuit's cell_ewma into
|
||||
* the active_circuits_pqueue.
|
||||
*/
|
||||
|
||||
static void
|
||||
ewma_notify_circ_active(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(pol_data);
|
||||
tor_assert(circ);
|
||||
tor_assert(pol_circ_data);
|
||||
|
||||
pol = TO_EWMA_POL_DATA(pol_data);
|
||||
cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data);
|
||||
|
||||
add_cell_ewma(pol, &(cdata->cell_ewma));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle circuit deactivation; this removes the circuit's cell_ewma from
|
||||
* the active_circuits_pqueue.
|
||||
*/
|
||||
|
||||
static void
|
||||
ewma_notify_circ_inactive(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(pol_data);
|
||||
tor_assert(circ);
|
||||
tor_assert(pol_circ_data);
|
||||
|
||||
pol = TO_EWMA_POL_DATA(pol_data);
|
||||
cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data);
|
||||
|
||||
remove_cell_ewma(pol, &(cdata->cell_ewma));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cell_ewma for this circuit after we've sent some cells, and
|
||||
* remove/reinsert it in the queue. This used to be done (brokenly,
|
||||
* see bug 6816) in channel_flush_from_first_active_circuit().
|
||||
*/
|
||||
|
||||
static void
|
||||
ewma_notify_xmit_cells(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data,
|
||||
circuit_t *circ,
|
||||
circuitmux_policy_circ_data_t *pol_circ_data,
|
||||
unsigned int n_cells)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
unsigned int tick;
|
||||
double fractional_tick, ewma_increment;
|
||||
/* The current (hi-res) time */
|
||||
struct timeval now_hires;
|
||||
cell_ewma_t *cell_ewma, *tmp;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(pol_data);
|
||||
tor_assert(circ);
|
||||
tor_assert(pol_circ_data);
|
||||
tor_assert(n_cells > 0);
|
||||
|
||||
pol = TO_EWMA_POL_DATA(pol_data);
|
||||
cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data);
|
||||
|
||||
/* Rescale the EWMAs if needed */
|
||||
tor_gettimeofday_cached(&now_hires);
|
||||
tick = cell_ewma_tick_from_timeval(&now_hires, &fractional_tick);
|
||||
|
||||
if (tick != pol->active_circuit_pqueue_last_recalibrated) {
|
||||
scale_active_circuits(pol, tick);
|
||||
}
|
||||
|
||||
/* How much do we adjust the cell count in cell_ewma by? */
|
||||
ewma_increment =
|
||||
((double)(n_cells)) * pow(ewma_scale_factor, -fractional_tick);
|
||||
|
||||
/* Do the adjustment */
|
||||
cell_ewma = &(cdata->cell_ewma);
|
||||
cell_ewma->cell_count += ewma_increment;
|
||||
|
||||
/*
|
||||
* Since we just sent on this circuit, it should be at the head of
|
||||
* the queue. Pop the head, assert that it matches, then re-add.
|
||||
*/
|
||||
tmp = pop_first_cell_ewma(pol);
|
||||
tor_assert(tmp == cell_ewma);
|
||||
add_cell_ewma(pol, cell_ewma);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick the preferred circuit to send from; this will be the one with
|
||||
* the lowest EWMA value in the priority queue. This used to be done
|
||||
* in channel_flush_from_first_active_circuit().
|
||||
*/
|
||||
|
||||
static circuit_t *
|
||||
ewma_pick_active_circuit(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data)
|
||||
{
|
||||
ewma_policy_data_t *pol = NULL;
|
||||
circuit_t *circ = NULL;
|
||||
cell_ewma_t *cell_ewma = NULL;
|
||||
|
||||
tor_assert(cmux);
|
||||
tor_assert(pol_data);
|
||||
|
||||
pol = TO_EWMA_POL_DATA(pol_data);
|
||||
|
||||
if (smartlist_len(pol->active_circuit_pqueue) > 0) {
|
||||
/* Get the head of the queue */
|
||||
cell_ewma = smartlist_get(pol->active_circuit_pqueue, 0);
|
||||
circ = cell_ewma_to_circuit(cell_ewma);
|
||||
}
|
||||
|
||||
return circ;
|
||||
}
|
||||
|
||||
/** Helper for sorting cell_ewma_t values in their priority queue. */
|
||||
static int
|
||||
compare_cell_ewma_counts(const void *p1, const void *p2)
|
||||
{
|
||||
const cell_ewma_t *e1 = p1, *e2 = p2;
|
||||
|
||||
if (e1->cell_count < e2->cell_count)
|
||||
return -1;
|
||||
else if (e1->cell_count > e2->cell_count)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Given a cell_ewma_t, return a pointer to the circuit containing it. */
|
||||
static circuit_t *
|
||||
cell_ewma_to_circuit(cell_ewma_t *ewma)
|
||||
{
|
||||
ewma_policy_circ_data_t *cdata = NULL;
|
||||
|
||||
tor_assert(ewma);
|
||||
cdata = SUBTYPE_P(ewma, ewma_policy_circ_data_t, cell_ewma);
|
||||
tor_assert(cdata);
|
||||
|
||||
return cdata->circ;
|
||||
}
|
||||
|
||||
/* ==== Functions for scaling cell_ewma_t ====
|
||||
|
||||
When choosing which cells to relay first, we favor circuits that have been
|
||||
quiet recently. This gives better latency on connections that aren't
|
||||
pushing lots of data, and makes the network feel more interactive.
|
||||
|
||||
Conceptually, we take an exponentially weighted mean average of the number
|
||||
of cells a circuit has sent, and allow active circuits (those with cells to
|
||||
relay) to send cells in reverse order of their exponentially-weighted mean
|
||||
average (EWMA) cell count. [That is, a cell sent N seconds ago 'counts'
|
||||
F^N times as much as a cell sent now, for 0<F<1.0, and we favor the
|
||||
circuit that has sent the fewest cells]
|
||||
|
||||
If 'double' had infinite precision, we could do this simply by counting a
|
||||
cell sent at startup as having weight 1.0, and a cell sent N seconds later
|
||||
as having weight F^-N. This way, we would never need to re-scale
|
||||
any already-sent cells.
|
||||
|
||||
To prevent double from overflowing, we could count a cell sent now as
|
||||
having weight 1.0 and a cell sent N seconds ago as having weight F^N.
|
||||
This, however, would mean we'd need to re-scale *ALL* old circuits every
|
||||
time we wanted to send a cell.
|
||||
|
||||
So as a compromise, we divide time into 'ticks' (currently, 10-second
|
||||
increments) and say that a cell sent at the start of a current tick is
|
||||
worth 1.0, a cell sent N seconds before the start of the current tick is
|
||||
worth F^N, and a cell sent N seconds after the start of the current tick is
|
||||
worth F^-N. This way we don't overflow, and we don't need to constantly
|
||||
rescale.
|
||||
*/
|
||||
|
||||
/** Given a timeval <b>now</b>, compute the cell_ewma tick in which it occurs
|
||||
* and the fraction of the tick that has elapsed between the start of the tick
|
||||
* and <b>now</b>. Return the former and store the latter in
|
||||
* *<b>remainder_out</b>.
|
||||
*
|
||||
* These tick values are not meant to be shared between Tor instances, or used
|
||||
* for other purposes. */
|
||||
|
||||
static unsigned
|
||||
cell_ewma_tick_from_timeval(const struct timeval *now,
|
||||
double *remainder_out)
|
||||
{
|
||||
unsigned res = (unsigned) (now->tv_sec / EWMA_TICK_LEN);
|
||||
/* rem */
|
||||
double rem = (now->tv_sec % EWMA_TICK_LEN) +
|
||||
((double)(now->tv_usec)) / 1.0e6;
|
||||
*remainder_out = rem / EWMA_TICK_LEN;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Tell the caller whether ewma_enabled is set */
|
||||
int
|
||||
cell_ewma_enabled(void)
|
||||
{
|
||||
return ewma_enabled;
|
||||
}
|
||||
|
||||
/** Compute and return the current cell_ewma tick. */
|
||||
unsigned int
|
||||
cell_ewma_get_tick(void)
|
||||
{
|
||||
return ((unsigned)approx_time() / EWMA_TICK_LEN);
|
||||
}
|
||||
|
||||
/** Adjust the global cell scale factor based on <b>options</b> */
|
||||
void
|
||||
cell_ewma_set_scale_factor(const or_options_t *options,
|
||||
const networkstatus_t *consensus)
|
||||
{
|
||||
int32_t halflife_ms;
|
||||
double halflife;
|
||||
const char *source;
|
||||
if (options && options->CircuitPriorityHalflife >= -EPSILON) {
|
||||
halflife = options->CircuitPriorityHalflife;
|
||||
source = "CircuitPriorityHalflife in configuration";
|
||||
} else if (consensus && (halflife_ms = networkstatus_get_param(
|
||||
consensus, "CircuitPriorityHalflifeMsec",
|
||||
-1, -1, INT32_MAX)) >= 0) {
|
||||
halflife = ((double)halflife_ms)/1000.0;
|
||||
source = "CircuitPriorityHalflifeMsec in consensus";
|
||||
} else {
|
||||
halflife = EWMA_DEFAULT_HALFLIFE;
|
||||
source = "Default value";
|
||||
}
|
||||
|
||||
if (halflife <= EPSILON) {
|
||||
/* The cell EWMA algorithm is disabled. */
|
||||
ewma_scale_factor = 0.1;
|
||||
ewma_enabled = 0;
|
||||
log_info(LD_OR,
|
||||
"Disabled cell_ewma algorithm because of value in %s",
|
||||
source);
|
||||
} else {
|
||||
/* convert halflife into halflife-per-tick. */
|
||||
halflife /= EWMA_TICK_LEN;
|
||||
/* compute per-tick scale factor. */
|
||||
ewma_scale_factor = exp( LOG_ONEHALF / halflife );
|
||||
ewma_enabled = 1;
|
||||
log_info(LD_OR,
|
||||
"Enabled cell_ewma algorithm because of value in %s; "
|
||||
"scale factor is %f per %d seconds",
|
||||
source, ewma_scale_factor, EWMA_TICK_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the multiplier necessary to convert the value of a cell sent in
|
||||
* 'from_tick' to one sent in 'to_tick'. */
|
||||
static INLINE double
|
||||
get_scale_factor(unsigned from_tick, unsigned to_tick)
|
||||
{
|
||||
/* This math can wrap around, but that's okay: unsigned overflow is
|
||||
well-defined */
|
||||
int diff = (int)(to_tick - from_tick);
|
||||
return pow(ewma_scale_factor, diff);
|
||||
}
|
||||
|
||||
/** Adjust the cell count of <b>ewma</b> so that it is scaled with respect to
|
||||
* <b>cur_tick</b> */
|
||||
static void
|
||||
scale_single_cell_ewma(cell_ewma_t *ewma, unsigned cur_tick)
|
||||
{
|
||||
double factor = get_scale_factor(ewma->last_adjusted_tick, cur_tick);
|
||||
ewma->cell_count *= factor;
|
||||
ewma->last_adjusted_tick = cur_tick;
|
||||
}
|
||||
|
||||
/** Adjust the cell count of every active circuit on <b>chan</b> so
|
||||
* that they are scaled with respect to <b>cur_tick</b> */
|
||||
static void
|
||||
scale_active_circuits(ewma_policy_data_t *pol, unsigned cur_tick)
|
||||
{
|
||||
double factor;
|
||||
|
||||
tor_assert(pol);
|
||||
tor_assert(pol->active_circuit_pqueue);
|
||||
|
||||
factor =
|
||||
get_scale_factor(
|
||||
pol->active_circuit_pqueue_last_recalibrated,
|
||||
cur_tick);
|
||||
/** Ordinarily it isn't okay to change the value of an element in a heap,
|
||||
* but it's okay here, since we are preserving the order. */
|
||||
SMARTLIST_FOREACH_BEGIN(
|
||||
pol->active_circuit_pqueue,
|
||||
cell_ewma_t *, e) {
|
||||
tor_assert(e->last_adjusted_tick ==
|
||||
pol->active_circuit_pqueue_last_recalibrated);
|
||||
e->cell_count *= factor;
|
||||
e->last_adjusted_tick = cur_tick;
|
||||
} SMARTLIST_FOREACH_END(e);
|
||||
pol->active_circuit_pqueue_last_recalibrated = cur_tick;
|
||||
}
|
||||
|
||||
/** Rescale <b>ewma</b> to the same scale as <b>pol</b>, and add it to
|
||||
* <b>pol</b>'s priority queue of active circuits */
|
||||
static void
|
||||
add_cell_ewma(ewma_policy_data_t *pol, cell_ewma_t *ewma)
|
||||
{
|
||||
tor_assert(pol);
|
||||
tor_assert(pol->active_circuit_pqueue);
|
||||
tor_assert(ewma);
|
||||
tor_assert(ewma->heap_index == -1);
|
||||
|
||||
scale_single_cell_ewma(
|
||||
ewma,
|
||||
pol->active_circuit_pqueue_last_recalibrated);
|
||||
|
||||
smartlist_pqueue_add(pol->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||
ewma);
|
||||
}
|
||||
|
||||
/** Remove <b>ewma</b> from <b>pol</b>'s priority queue of active circuits */
|
||||
static void
|
||||
remove_cell_ewma(ewma_policy_data_t *pol, cell_ewma_t *ewma)
|
||||
{
|
||||
tor_assert(pol);
|
||||
tor_assert(pol->active_circuit_pqueue);
|
||||
tor_assert(ewma);
|
||||
tor_assert(ewma->heap_index != -1);
|
||||
|
||||
smartlist_pqueue_remove(pol->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index),
|
||||
ewma);
|
||||
}
|
||||
|
||||
/** Remove and return the first cell_ewma_t from pol's priority queue of
|
||||
* active circuits. Requires that the priority queue is nonempty. */
|
||||
static cell_ewma_t *
|
||||
pop_first_cell_ewma(ewma_policy_data_t *pol)
|
||||
{
|
||||
tor_assert(pol);
|
||||
tor_assert(pol->active_circuit_pqueue);
|
||||
|
||||
return smartlist_pqueue_pop(pol->active_circuit_pqueue,
|
||||
compare_cell_ewma_counts,
|
||||
STRUCT_OFFSET(cell_ewma_t, heap_index));
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/* * Copyright (c) 2012-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitmux_ewma.h
|
||||
* \brief Header file for circuitmux_ewma.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITMUX_EWMA_H
|
||||
#define TOR_CIRCUITMUX_EWMA_H
|
||||
|
||||
#include "or.h"
|
||||
#include "circuitmux.h"
|
||||
|
||||
/* Everything but circuitmux_ewma.c should see this extern */
|
||||
#ifndef TOR_CIRCUITMUX_EWMA_C_
|
||||
|
||||
extern circuitmux_policy_t ewma_policy;
|
||||
|
||||
#endif /* !(TOR_CIRCUITMUX_EWMA_C_) */
|
||||
|
||||
/* Externally visible EWMA functions */
|
||||
int cell_ewma_enabled(void);
|
||||
unsigned int cell_ewma_get_tick(void);
|
||||
void cell_ewma_set_scale_factor(const or_options_t *options,
|
||||
const networkstatus_t *consensus);
|
||||
|
||||
#endif /* TOR_CIRCUITMUX_EWMA_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,98 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuitstats.h
|
||||
* \brief Header file for circuitstats.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITSTATS_H
|
||||
#define TOR_CIRCUITSTATS_H
|
||||
|
||||
const circuit_build_times_t *get_circuit_build_times(void);
|
||||
circuit_build_times_t *get_circuit_build_times_mutable(void);
|
||||
double get_circuit_build_close_time_ms(void);
|
||||
double get_circuit_build_timeout_ms(void);
|
||||
|
||||
int circuit_build_times_disabled(void);
|
||||
int circuit_build_times_enough_to_compute(const circuit_build_times_t *cbt);
|
||||
void circuit_build_times_update_state(const circuit_build_times_t *cbt,
|
||||
or_state_t *state);
|
||||
int circuit_build_times_parse_state(circuit_build_times_t *cbt,
|
||||
or_state_t *state);
|
||||
void circuit_build_times_count_timeout(circuit_build_times_t *cbt,
|
||||
int did_onehop);
|
||||
int circuit_build_times_count_close(circuit_build_times_t *cbt,
|
||||
int did_onehop, time_t start_time);
|
||||
void circuit_build_times_set_timeout(circuit_build_times_t *cbt);
|
||||
int circuit_build_times_add_time(circuit_build_times_t *cbt,
|
||||
build_time_t time);
|
||||
int circuit_build_times_needs_circuits(const circuit_build_times_t *cbt);
|
||||
|
||||
int circuit_build_times_needs_circuits_now(const circuit_build_times_t *cbt);
|
||||
void circuit_build_times_init(circuit_build_times_t *cbt);
|
||||
void circuit_build_times_free_timeouts(circuit_build_times_t *cbt);
|
||||
void circuit_build_times_new_consensus_params(circuit_build_times_t *cbt,
|
||||
networkstatus_t *ns);
|
||||
double circuit_build_times_timeout_rate(const circuit_build_times_t *cbt);
|
||||
double circuit_build_times_close_rate(const circuit_build_times_t *cbt);
|
||||
|
||||
void circuit_build_times_update_last_circ(circuit_build_times_t *cbt);
|
||||
|
||||
#ifdef CIRCUITSTATS_PRIVATE
|
||||
STATIC double circuit_build_times_calculate_timeout(circuit_build_times_t *cbt,
|
||||
double quantile);
|
||||
STATIC int circuit_build_times_update_alpha(circuit_build_times_t *cbt);
|
||||
STATIC void circuit_build_times_reset(circuit_build_times_t *cbt);
|
||||
|
||||
/* Network liveness functions */
|
||||
STATIC int circuit_build_times_network_check_changed(
|
||||
circuit_build_times_t *cbt);
|
||||
#endif
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
build_time_t circuit_build_times_generate_sample(circuit_build_times_t *cbt,
|
||||
double q_lo, double q_hi);
|
||||
double circuit_build_times_cdf(circuit_build_times_t *cbt, double x);
|
||||
void circuit_build_times_initial_alpha(circuit_build_times_t *cbt,
|
||||
double quantile, double time_ms);
|
||||
void circuitbuild_running_unit_tests(void);
|
||||
#endif
|
||||
|
||||
/* Network liveness functions */
|
||||
void circuit_build_times_network_is_live(circuit_build_times_t *cbt);
|
||||
int circuit_build_times_network_check_live(const circuit_build_times_t *cbt);
|
||||
void circuit_build_times_network_circ_success(circuit_build_times_t *cbt);
|
||||
|
||||
#ifdef CIRCUITSTATS_PRIVATE
|
||||
/** Structure for circuit build times history */
|
||||
struct circuit_build_times_s {
|
||||
/** The circular array of recorded build times in milliseconds */
|
||||
build_time_t circuit_build_times[CBT_NCIRCUITS_TO_OBSERVE];
|
||||
/** Current index in the circuit_build_times circular array */
|
||||
int build_times_idx;
|
||||
/** Total number of build times accumulated. Max CBT_NCIRCUITS_TO_OBSERVE */
|
||||
int total_build_times;
|
||||
/** Information about the state of our local network connection */
|
||||
network_liveness_t liveness;
|
||||
/** Last time we built a circuit. Used to decide to build new test circs */
|
||||
time_t last_circ_at;
|
||||
/** "Minimum" value of our pareto distribution (actually mode) */
|
||||
build_time_t Xm;
|
||||
/** alpha exponent for pareto dist. */
|
||||
double alpha;
|
||||
/** Have we computed a timeout? */
|
||||
int have_computed_timeout;
|
||||
/** The exact value for that timeout in milliseconds. Stored as a double
|
||||
* to maintain precision from calculations to and from quantile value. */
|
||||
double timeout_ms;
|
||||
/** How long we wait before actually closing the circuit. */
|
||||
double close_ms;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file circuituse.h
|
||||
* \brief Header file for circuituse.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CIRCUITUSE_H
|
||||
#define TOR_CIRCUITUSE_H
|
||||
|
||||
void circuit_expire_building(void);
|
||||
void circuit_remove_handled_ports(smartlist_t *needed_ports);
|
||||
int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port,
|
||||
int min);
|
||||
#if 0
|
||||
int circuit_conforms_to_options(const origin_circuit_t *circ,
|
||||
const or_options_t *options);
|
||||
#endif
|
||||
void circuit_build_needed_circs(time_t now);
|
||||
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
|
||||
|
||||
void circuit_expire_old_circuits_serverside(time_t now);
|
||||
|
||||
void reset_bandwidth_test(void);
|
||||
int circuit_enough_testing_circs(void);
|
||||
|
||||
void circuit_has_opened(origin_circuit_t *circ);
|
||||
void circuit_try_attaching_streams(origin_circuit_t *circ);
|
||||
void circuit_build_failed(origin_circuit_t *circ);
|
||||
|
||||
/** Flag to set when a circuit should have only a single hop. */
|
||||
#define CIRCLAUNCH_ONEHOP_TUNNEL (1<<0)
|
||||
/** Flag to set when a circuit needs to be built of high-uptime nodes */
|
||||
#define CIRCLAUNCH_NEED_UPTIME (1<<1)
|
||||
/** Flag to set when a circuit needs to be built of high-capacity nodes */
|
||||
#define CIRCLAUNCH_NEED_CAPACITY (1<<2)
|
||||
/** Flag to set when the last hop of a circuit doesn't need to be an
|
||||
* exit node. */
|
||||
#define CIRCLAUNCH_IS_INTERNAL (1<<3)
|
||||
origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
|
||||
extend_info_t *info,
|
||||
int flags);
|
||||
origin_circuit_t *circuit_launch(uint8_t purpose, int flags);
|
||||
void circuit_reset_failure_count(int timeout);
|
||||
int connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
|
||||
origin_circuit_t *circ,
|
||||
crypt_path_t *cpath);
|
||||
int connection_ap_handshake_attach_circuit(entry_connection_t *conn);
|
||||
|
||||
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose);
|
||||
|
||||
int hostname_in_track_host_exits(const or_options_t *options,
|
||||
const char *address);
|
||||
void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,589 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file command.c
|
||||
* \brief Functions for processing incoming cells.
|
||||
**/
|
||||
|
||||
/* In-points to command.c:
|
||||
*
|
||||
* - command_process_cell(), called from
|
||||
* incoming cell handlers of channel_t instances;
|
||||
* callbacks registered in command_setup_channel(),
|
||||
* called when channels are created in circuitbuild.c
|
||||
*/
|
||||
#include "or.h"
|
||||
#include "channel.h"
|
||||
#include "circuitbuild.h"
|
||||
#include "circuitlist.h"
|
||||
#include "command.h"
|
||||
#include "connection.h"
|
||||
#include "connection_or.h"
|
||||
#include "config.h"
|
||||
#include "control.h"
|
||||
#include "cpuworker.h"
|
||||
#include "hibernate.h"
|
||||
#include "nodelist.h"
|
||||
#include "onion.h"
|
||||
#include "rephist.h"
|
||||
#include "relay.h"
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
|
||||
/** How many CELL_CREATE cells have we received, ever? */
|
||||
uint64_t stats_n_create_cells_processed = 0;
|
||||
/** How many CELL_CREATED cells have we received, ever? */
|
||||
uint64_t stats_n_created_cells_processed = 0;
|
||||
/** How many CELL_RELAY cells have we received, ever? */
|
||||
uint64_t stats_n_relay_cells_processed = 0;
|
||||
/** How many CELL_DESTROY cells have we received, ever? */
|
||||
uint64_t stats_n_destroy_cells_processed = 0;
|
||||
|
||||
/* Handle an incoming channel */
|
||||
static void command_handle_incoming_channel(channel_listener_t *listener,
|
||||
channel_t *chan);
|
||||
|
||||
/* These are the main functions for processing cells */
|
||||
static void command_process_create_cell(cell_t *cell, channel_t *chan);
|
||||
static void command_process_created_cell(cell_t *cell, channel_t *chan);
|
||||
static void command_process_relay_cell(cell_t *cell, channel_t *chan);
|
||||
static void command_process_destroy_cell(cell_t *cell, channel_t *chan);
|
||||
|
||||
/** Convert the cell <b>command</b> into a lower-case, human-readable
|
||||
* string. */
|
||||
const char *
|
||||
cell_command_to_string(uint8_t command)
|
||||
{
|
||||
switch (command) {
|
||||
case CELL_PADDING: return "padding";
|
||||
case CELL_CREATE: return "create";
|
||||
case CELL_CREATED: return "created";
|
||||
case CELL_RELAY: return "relay";
|
||||
case CELL_DESTROY: return "destroy";
|
||||
case CELL_CREATE_FAST: return "create_fast";
|
||||
case CELL_CREATED_FAST: return "created_fast";
|
||||
case CELL_VERSIONS: return "versions";
|
||||
case CELL_NETINFO: return "netinfo";
|
||||
case CELL_RELAY_EARLY: return "relay_early";
|
||||
case CELL_CREATE2: return "create2";
|
||||
case CELL_CREATED2: return "created2";
|
||||
case CELL_VPADDING: return "vpadding";
|
||||
case CELL_CERTS: return "certs";
|
||||
case CELL_AUTH_CHALLENGE: return "auth_challenge";
|
||||
case CELL_AUTHENTICATE: return "authenticate";
|
||||
case CELL_AUTHORIZE: return "authorize";
|
||||
default: return "unrecognized";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KEEP_TIMING_STATS
|
||||
/** This is a wrapper function around the actual function that processes the
|
||||
* <b>cell</b> that just arrived on <b>conn</b>. Increment <b>*time</b>
|
||||
* by the number of microseconds used by the call to <b>*func(cell, conn)</b>.
|
||||
*/
|
||||
static void
|
||||
command_time_process_cell(cell_t *cell, channel_t *chan, int *time,
|
||||
void (*func)(cell_t *, channel_t *))
|
||||
{
|
||||
struct timeval start, end;
|
||||
long time_passed;
|
||||
|
||||
tor_gettimeofday(&start);
|
||||
|
||||
(*func)(cell, chan);
|
||||
|
||||
tor_gettimeofday(&end);
|
||||
time_passed = tv_udiff(&start, &end) ;
|
||||
|
||||
if (time_passed > 10000) { /* more than 10ms */
|
||||
log_debug(LD_OR,"That call just took %ld ms.",time_passed/1000);
|
||||
}
|
||||
if (time_passed < 0) {
|
||||
log_info(LD_GENERAL,"That call took us back in time!");
|
||||
time_passed = 0;
|
||||
}
|
||||
*time += time_passed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Process a <b>cell</b> that was just received on <b>chan</b>. Keep internal
|
||||
* statistics about how many of each cell we've processed so far
|
||||
* this second, and the total number of microseconds it took to
|
||||
* process each type of cell.
|
||||
*/
|
||||
void
|
||||
command_process_cell(channel_t *chan, cell_t *cell)
|
||||
{
|
||||
#ifdef KEEP_TIMING_STATS
|
||||
/* how many of each cell have we seen so far this second? needs better
|
||||
* name. */
|
||||
static int num_create=0, num_created=0, num_relay=0, num_destroy=0;
|
||||
/* how long has it taken to process each type of cell? */
|
||||
static int create_time=0, created_time=0, relay_time=0, destroy_time=0;
|
||||
static time_t current_second = 0; /* from previous calls to time */
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now > current_second) { /* the second has rolled over */
|
||||
/* print stats */
|
||||
log_info(LD_OR,
|
||||
"At end of second: %d creates (%d ms), %d createds (%d ms), "
|
||||
"%d relays (%d ms), %d destroys (%d ms)",
|
||||
num_create, create_time/1000,
|
||||
num_created, created_time/1000,
|
||||
num_relay, relay_time/1000,
|
||||
num_destroy, destroy_time/1000);
|
||||
|
||||
/* zero out stats */
|
||||
num_create = num_created = num_relay = num_destroy = 0;
|
||||
create_time = created_time = relay_time = destroy_time = 0;
|
||||
|
||||
/* remember which second it is, for next time */
|
||||
current_second = now;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KEEP_TIMING_STATS
|
||||
#define PROCESS_CELL(tp, cl, cn) STMT_BEGIN { \
|
||||
++num ## tp; \
|
||||
command_time_process_cell(cl, cn, & tp ## time , \
|
||||
command_process_ ## tp ## _cell); \
|
||||
} STMT_END
|
||||
#else
|
||||
#define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
|
||||
#endif
|
||||
|
||||
switch (cell->command) {
|
||||
case CELL_CREATE:
|
||||
case CELL_CREATE_FAST:
|
||||
case CELL_CREATE2:
|
||||
++stats_n_create_cells_processed;
|
||||
PROCESS_CELL(create, cell, chan);
|
||||
break;
|
||||
case CELL_CREATED:
|
||||
case CELL_CREATED_FAST:
|
||||
case CELL_CREATED2:
|
||||
++stats_n_created_cells_processed;
|
||||
PROCESS_CELL(created, cell, chan);
|
||||
break;
|
||||
case CELL_RELAY:
|
||||
case CELL_RELAY_EARLY:
|
||||
++stats_n_relay_cells_processed;
|
||||
PROCESS_CELL(relay, cell, chan);
|
||||
break;
|
||||
case CELL_DESTROY:
|
||||
++stats_n_destroy_cells_processed;
|
||||
PROCESS_CELL(destroy, cell, chan);
|
||||
break;
|
||||
default:
|
||||
log_fn(LOG_INFO, LD_PROTOCOL,
|
||||
"Cell of unknown or unexpected type (%d) received. "
|
||||
"Dropping.",
|
||||
cell->command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Process an incoming var_cell from a channel; in the current protocol all
|
||||
* the var_cells are handshake-related and handled below the channel layer,
|
||||
* so this just logs a warning and drops the cell.
|
||||
*/
|
||||
|
||||
void
|
||||
command_process_var_cell(channel_t *chan, var_cell_t *var_cell)
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(var_cell);
|
||||
|
||||
log_info(LD_PROTOCOL,
|
||||
"Received unexpected var_cell above the channel layer of type %d"
|
||||
"; dropping it.",
|
||||
var_cell->command);
|
||||
}
|
||||
|
||||
/** Process a 'create' <b>cell</b> that just arrived from <b>chan</b>. Make a
|
||||
* new circuit with the p_circ_id specified in cell. Put the circuit in state
|
||||
* onionskin_pending, and pass the onionskin to the cpuworker. Circ will get
|
||||
* picked up again when the cpuworker finishes decrypting it.
|
||||
*/
|
||||
static void
|
||||
command_process_create_cell(cell_t *cell, channel_t *chan)
|
||||
{
|
||||
or_circuit_t *circ;
|
||||
const or_options_t *options = get_options();
|
||||
int id_is_high;
|
||||
create_cell_t *create_cell;
|
||||
|
||||
tor_assert(cell);
|
||||
tor_assert(chan);
|
||||
|
||||
log_debug(LD_OR,
|
||||
"Got a CREATE cell for circ_id %u on channel " U64_FORMAT
|
||||
" (%p)",
|
||||
(unsigned)cell->circ_id,
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
|
||||
if (we_are_hibernating()) {
|
||||
log_info(LD_OR,
|
||||
"Received create cell but we're shutting down. Sending back "
|
||||
"destroy.");
|
||||
channel_send_destroy(cell->circ_id, chan,
|
||||
END_CIRC_REASON_HIBERNATING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!server_mode(options) ||
|
||||
(!public_server_mode(options) && channel_is_outgoing(chan))) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received create cell (type %d) from %s, but we're connected "
|
||||
"to it as a client. "
|
||||
"Sending back a destroy.",
|
||||
(int)cell->command, channel_get_canonical_remote_descr(chan));
|
||||
channel_send_destroy(cell->circ_id, chan,
|
||||
END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cell->circ_id == 0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received a create cell (type %d) from %s with zero circID; "
|
||||
" ignoring.", (int)cell->command,
|
||||
channel_get_actual_remote_descr(chan));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the high bit of the circuit ID is not as expected, close the
|
||||
* circ. */
|
||||
if (chan->wide_circ_ids)
|
||||
id_is_high = cell->circ_id & (1u<<31);
|
||||
else
|
||||
id_is_high = cell->circ_id & (1u<<15);
|
||||
if ((id_is_high &&
|
||||
chan->circ_id_type == CIRC_ID_TYPE_HIGHER) ||
|
||||
(!id_is_high &&
|
||||
chan->circ_id_type == CIRC_ID_TYPE_LOWER)) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received create cell with unexpected circ_id %u. Closing.",
|
||||
(unsigned)cell->circ_id);
|
||||
channel_send_destroy(cell->circ_id, chan,
|
||||
END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (circuit_id_in_use_on_channel(cell->circ_id, chan)) {
|
||||
const node_t *node = node_get_by_id(chan->identity_digest);
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Received CREATE cell (circID %u) for known circ. "
|
||||
"Dropping (age %d).",
|
||||
(unsigned)cell->circ_id,
|
||||
(int)(time(NULL) - channel_when_created(chan)));
|
||||
if (node) {
|
||||
char *p = esc_for_log(node_get_platform(node));
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
|
||||
"Details: router %s, platform %s.",
|
||||
node_describe(node), p);
|
||||
tor_free(p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
circ = or_circuit_new(cell->circ_id, chan);
|
||||
circ->base_.purpose = CIRCUIT_PURPOSE_OR;
|
||||
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);
|
||||
create_cell = tor_malloc_zero(sizeof(create_cell_t));
|
||||
if (create_cell_parse(create_cell, cell) < 0) {
|
||||
tor_free(create_cell);
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||
"Bogus/unrecognized create cell; closing.");
|
||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (create_cell->handshake_type != ONION_HANDSHAKE_TYPE_FAST) {
|
||||
/* hand it off to the cpuworkers, and then return. */
|
||||
if (connection_or_digest_is_known_relay(chan->identity_digest))
|
||||
rep_hist_note_circuit_handshake_requested(create_cell->handshake_type);
|
||||
if (assign_onionskin_to_cpuworker(NULL, circ, create_cell) < 0) {
|
||||
log_debug(LD_GENERAL,"Failed to hand off onionskin. Closing.");
|
||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
|
||||
return;
|
||||
}
|
||||
log_debug(LD_OR,"success: handed off onionskin.");
|
||||
} else {
|
||||
/* This is a CREATE_FAST cell; we can handle it immediately without using
|
||||
* a CPU worker. */
|
||||
uint8_t keys[CPATH_KEY_MATERIAL_LEN];
|
||||
uint8_t rend_circ_nonce[DIGEST_LEN];
|
||||
int len;
|
||||
created_cell_t created_cell;
|
||||
|
||||
/* Make sure we never try to use the OR connection on which we
|
||||
* received this cell to satisfy an EXTEND request, */
|
||||
channel_mark_client(chan);
|
||||
|
||||
memset(&created_cell, 0, sizeof(created_cell));
|
||||
len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_FAST,
|
||||
create_cell->onionskin,
|
||||
create_cell->handshake_len,
|
||||
NULL,
|
||||
created_cell.reply,
|
||||
keys, CPATH_KEY_MATERIAL_LEN,
|
||||
rend_circ_nonce);
|
||||
tor_free(create_cell);
|
||||
if (len < 0) {
|
||||
log_warn(LD_OR,"Failed to generate key material. Closing.");
|
||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
||||
tor_free(create_cell);
|
||||
return;
|
||||
}
|
||||
created_cell.cell_type = CELL_CREATED_FAST;
|
||||
created_cell.handshake_len = len;
|
||||
|
||||
if (onionskin_answer(circ, &created_cell,
|
||||
(const char *)keys, rend_circ_nonce)<0) {
|
||||
log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing.");
|
||||
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
|
||||
return;
|
||||
}
|
||||
memwipe(keys, 0, sizeof(keys));
|
||||
}
|
||||
}
|
||||
|
||||
/** Process a 'created' <b>cell</b> that just arrived from <b>chan</b>.
|
||||
* Find the circuit
|
||||
* that it's intended for. If we're not the origin of the circuit, package
|
||||
* the 'created' cell in an 'extended' relay cell and pass it back. If we
|
||||
* are the origin of the circuit, send it to circuit_finish_handshake() to
|
||||
* finish processing keys, and then call circuit_send_next_onion_skin() to
|
||||
* extend to the next hop in the circuit if necessary.
|
||||
*/
|
||||
static void
|
||||
command_process_created_cell(cell_t *cell, channel_t *chan)
|
||||
{
|
||||
circuit_t *circ;
|
||||
extended_cell_t extended_cell;
|
||||
|
||||
circ = circuit_get_by_circid_channel(cell->circ_id, chan);
|
||||
|
||||
if (!circ) {
|
||||
log_info(LD_OR,
|
||||
"(circID %u) unknown circ (probably got a destroy earlier). "
|
||||
"Dropping.", (unsigned)cell->circ_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (circ->n_circ_id != cell->circ_id) {
|
||||
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
|
||||
"got created cell from Tor client? Closing.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (created_cell_parse(&extended_cell.created_cell, cell) < 0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR, "Unparseable created cell.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CIRCUIT_IS_ORIGIN(circ)) { /* we're the OP. Handshake this. */
|
||||
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
||||
int err_reason = 0;
|
||||
log_debug(LD_OR,"at OP. Finishing handshake.");
|
||||
if ((err_reason = circuit_finish_handshake(origin_circ,
|
||||
&extended_cell.created_cell)) < 0) {
|
||||
log_warn(LD_OR,"circuit_finish_handshake failed.");
|
||||
circuit_mark_for_close(circ, -err_reason);
|
||||
return;
|
||||
}
|
||||
log_debug(LD_OR,"Moving to next skin.");
|
||||
if ((err_reason = circuit_send_next_onion_skin(origin_circ)) < 0) {
|
||||
log_info(LD_OR,"circuit_send_next_onion_skin failed.");
|
||||
/* XXX push this circuit_close lower */
|
||||
circuit_mark_for_close(circ, -err_reason);
|
||||
return;
|
||||
}
|
||||
} else { /* pack it into an extended relay cell, and send it. */
|
||||
uint8_t command=0;
|
||||
uint16_t len=0;
|
||||
uint8_t payload[RELAY_PAYLOAD_SIZE];
|
||||
log_debug(LD_OR,
|
||||
"Converting created cell to extended relay cell, sending.");
|
||||
memset(payload, 0, sizeof(payload));
|
||||
if (extended_cell.created_cell.cell_type == CELL_CREATED2)
|
||||
extended_cell.cell_type = RELAY_COMMAND_EXTENDED2;
|
||||
else
|
||||
extended_cell.cell_type = RELAY_COMMAND_EXTENDED;
|
||||
if (extended_cell_format(&command, &len, payload, &extended_cell) < 0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR, "Can't format extended cell.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
relay_send_command_from_edge(0, circ, command,
|
||||
(const char*)payload, len, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/** Process a 'relay' or 'relay_early' <b>cell</b> that just arrived from
|
||||
* <b>conn</b>. Make sure it came in with a recognized circ_id. Pass it on to
|
||||
* circuit_receive_relay_cell() for actual processing.
|
||||
*/
|
||||
static void
|
||||
command_process_relay_cell(cell_t *cell, channel_t *chan)
|
||||
{
|
||||
circuit_t *circ;
|
||||
int reason, direction;
|
||||
|
||||
circ = circuit_get_by_circid_channel(cell->circ_id, chan);
|
||||
|
||||
if (!circ) {
|
||||
log_debug(LD_OR,
|
||||
"unknown circuit %u on connection from %s. Dropping.",
|
||||
(unsigned)cell->circ_id,
|
||||
channel_get_canonical_remote_descr(chan));
|
||||
return;
|
||||
}
|
||||
|
||||
if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
|
||||
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit in create_wait. Closing.");
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CIRCUIT_IS_ORIGIN(circ)) {
|
||||
/* if we're a relay and treating connections with recent local
|
||||
* traffic better, then this is one of them. */
|
||||
channel_timestamp_client(chan);
|
||||
}
|
||||
|
||||
if (!CIRCUIT_IS_ORIGIN(circ) &&
|
||||
cell->circ_id == TO_OR_CIRCUIT(circ)->p_circ_id)
|
||||
direction = CELL_DIRECTION_OUT;
|
||||
else
|
||||
direction = CELL_DIRECTION_IN;
|
||||
|
||||
/* If we have a relay_early cell, make sure that it's outbound, and we've
|
||||
* gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
|
||||
if (cell->command == CELL_RELAY_EARLY) {
|
||||
if (direction == CELL_DIRECTION_IN) {
|
||||
/* Allow an unlimited number of inbound relay_early cells,
|
||||
* for hidden service compatibility. There isn't any way to make
|
||||
* a long circuit through inbound relay_early cells anyway. See
|
||||
* bug 1038. -RD */
|
||||
} else {
|
||||
or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
|
||||
if (or_circ->remaining_relay_early_cells == 0) {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_OR,
|
||||
"Received too many RELAY_EARLY cells on circ %u from %s."
|
||||
" Closing circuit.",
|
||||
(unsigned)cell->circ_id,
|
||||
safe_str(channel_get_canonical_remote_descr(chan)));
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
|
||||
return;
|
||||
}
|
||||
--or_circ->remaining_relay_early_cells;
|
||||
}
|
||||
}
|
||||
|
||||
if ((reason = circuit_receive_relay_cell(cell, circ, direction)) < 0) {
|
||||
log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit_receive_relay_cell "
|
||||
"(%s) failed. Closing.",
|
||||
direction==CELL_DIRECTION_OUT?"forward":"backward");
|
||||
circuit_mark_for_close(circ, -reason);
|
||||
}
|
||||
}
|
||||
|
||||
/** Process a 'destroy' <b>cell</b> that just arrived from
|
||||
* <b>chan</b>. Find the circ that it refers to (if any).
|
||||
*
|
||||
* If the circ is in state
|
||||
* onionskin_pending, then call onion_pending_remove() to remove it
|
||||
* from the pending onion list (note that if it's already being
|
||||
* processed by the cpuworker, it won't be in the list anymore; but
|
||||
* when the cpuworker returns it, the circuit will be gone, and the
|
||||
* cpuworker response will be dropped).
|
||||
*
|
||||
* Then mark the circuit for close (which marks all edges for close,
|
||||
* and passes the destroy cell onward if necessary).
|
||||
*/
|
||||
static void
|
||||
command_process_destroy_cell(cell_t *cell, channel_t *chan)
|
||||
{
|
||||
circuit_t *circ;
|
||||
int reason;
|
||||
|
||||
circ = circuit_get_by_circid_channel(cell->circ_id, chan);
|
||||
if (!circ) {
|
||||
log_info(LD_OR,"unknown circuit %u on connection from %s. Dropping.",
|
||||
(unsigned)cell->circ_id,
|
||||
channel_get_canonical_remote_descr(chan));
|
||||
return;
|
||||
}
|
||||
log_debug(LD_OR,"Received for circID %u.",(unsigned)cell->circ_id);
|
||||
|
||||
reason = (uint8_t)cell->payload[0];
|
||||
circ->received_destroy = 1;
|
||||
|
||||
if (!CIRCUIT_IS_ORIGIN(circ) &&
|
||||
cell->circ_id == TO_OR_CIRCUIT(circ)->p_circ_id) {
|
||||
/* the destroy came from behind */
|
||||
circuit_set_p_circid_chan(TO_OR_CIRCUIT(circ), 0, NULL);
|
||||
circuit_mark_for_close(circ, reason|END_CIRC_REASON_FLAG_REMOTE);
|
||||
} else { /* the destroy came from ahead */
|
||||
circuit_set_n_circid_chan(circ, 0, NULL);
|
||||
if (CIRCUIT_IS_ORIGIN(circ)) {
|
||||
circuit_mark_for_close(circ, reason|END_CIRC_REASON_FLAG_REMOTE);
|
||||
} else {
|
||||
char payload[1];
|
||||
log_debug(LD_OR, "Delivering 'truncated' back.");
|
||||
payload[0] = (char)reason;
|
||||
relay_send_command_from_edge(0, circ, RELAY_COMMAND_TRUNCATED,
|
||||
payload, sizeof(payload), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback to handle a new channel; call command_setup_channel() to give
|
||||
* it the right cell handlers.
|
||||
*/
|
||||
|
||||
static void
|
||||
command_handle_incoming_channel(channel_listener_t *listener, channel_t *chan)
|
||||
{
|
||||
tor_assert(listener);
|
||||
tor_assert(chan);
|
||||
|
||||
command_setup_channel(chan);
|
||||
}
|
||||
|
||||
/** Given a channel, install the right handlers to process incoming
|
||||
* cells on it.
|
||||
*/
|
||||
|
||||
void
|
||||
command_setup_channel(channel_t *chan)
|
||||
{
|
||||
tor_assert(chan);
|
||||
|
||||
channel_set_cell_handlers(chan,
|
||||
command_process_cell,
|
||||
command_process_var_cell);
|
||||
}
|
||||
|
||||
/** Given a listener, install the right handler to process incoming
|
||||
* channels on it.
|
||||
*/
|
||||
|
||||
void
|
||||
command_setup_listener(channel_listener_t *listener)
|
||||
{
|
||||
tor_assert(listener);
|
||||
tor_assert(listener->state == CHANNEL_LISTENER_STATE_LISTENING);
|
||||
|
||||
channel_listener_set_listener_fn(listener, command_handle_incoming_channel);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file command.h
|
||||
* \brief Header file for command.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_COMMAND_H
|
||||
#define TOR_COMMAND_H
|
||||
|
||||
#include "channel.h"
|
||||
|
||||
void command_process_cell(channel_t *chan, cell_t *cell);
|
||||
void command_process_var_cell(channel_t *chan, var_cell_t *cell);
|
||||
void command_setup_channel(channel_t *chan);
|
||||
void command_setup_listener(channel_listener_t *chan_l);
|
||||
|
||||
const char *cell_command_to_string(uint8_t command);
|
||||
|
||||
extern uint64_t stats_n_padding_cells_processed;
|
||||
extern uint64_t stats_n_create_cells_processed;
|
||||
extern uint64_t stats_n_created_cells_processed;
|
||||
extern uint64_t stats_n_relay_cells_processed;
|
||||
extern uint64_t stats_n_destroy_cells_processed;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
"10e0ec8ee3318e6a5ebbedc35d45ad4ec2fe5bb2 src/common/aes.c\n"
|
||||
"7fdacbf7fc104d4e118ce06cf823b2f3cb145291 src/common/crypto.c\n"
|
||||
"401d6c1243b8d99ad8f64dba232e234e60a59eb7 src/common/crypto_format.c\n"
|
||||
"64a20b8425300b0bf2373a4fe4eb74b47c4baf50 src/common/torgzip.c\n"
|
||||
"f0e8fd88f7198ad4adbd5c28e4af909b2d553b5a src/common/tortls.c\n"
|
||||
"05dc726d9d47888cc75a1c3bd31c8214dc2cb581 src/common/crypto_curve25519.c\n"
|
||||
"d233965a57506745525c7a78ff2911d59f5e3743 src/common/address.h\n"
|
||||
"ac6a50ceb318ed6907b5804034b98172ffc5ff83 src/common/backtrace.h\n"
|
||||
"947ef902f15f556f176b1115f09d9966e377347d src/common/aes.h\n"
|
||||
"6fb51902eea04b5c33a99a754845958fec43d912 src/common/ciphers.inc\n"
|
||||
"4618a9860688c2cb12d37d8172317324c10f0a92 src/common/tor_compat.h\n"
|
||||
"e427c754391f1282a98cbbb387bae2ae403cbde7 src/common/compat_libevent.h\n"
|
||||
"faaa0bcfcc0cbc61f6d092b9b36e56cb89b090b7 src/common/container.h\n"
|
||||
"7196fde86ec70bd579e8fcd546817d285d936b18 src/common/crypto.h\n"
|
||||
"1260154e3b65f2586a54986deffec6963a4c7204 src/common/crypto_curve25519.h\n"
|
||||
"9ed1bb165e8d0532cae5bfd17e27d037d2a05bf4 src/common/di_ops.h\n"
|
||||
"697be45dc2e1ae6537b34dc72abf6394952a1b87 src/common/memarea.h\n"
|
||||
"0b594bada47b6e23358fa924cffbf24e01180d60 src/common/mempool.h\n"
|
||||
"2cd7af59a82d4e1ca2873d2801c44176605a545a src/common/procmon.h\n"
|
||||
"ed8b5d4225ceaf11e29fe635a091e2b2f3fe3ae8 src/common/sandbox.h\n"
|
||||
"ddfdca2f5d52acc27214a3c91c0ca73c81b526eb src/common/testsupport.h\n"
|
||||
"13108dc9184a7ece65685e0724e7e8770acd576f src/common/torgzip.h\n"
|
||||
"8d71f0488728c324a5aabfd92d209350973b490a src/common/torint.h\n"
|
||||
"b86f76bfdfdc3bd841233c662761e857cb830c88 src/common/torlog.h\n"
|
||||
"27209a8a0e9b8c61bbbb2d50241a2a4b4595ce19 src/common/tortls.h\n"
|
||||
"e5cb074466d9f59f1988e8964fed1476c238ff14 src/common/tor_util.h\n"
|
||||
-3254
File diff suppressed because it is too large
Load Diff
@@ -1,663 +0,0 @@
|
||||
/* Copyright (c) 2009-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file compat_libevent.c
|
||||
* \brief Wrappers to handle porting between different versions of libevent.
|
||||
*
|
||||
* In an ideal world, we'd just use Libevent 2.0 from now on. But as of June
|
||||
* 2012, Libevent 1.4 is still all over, and some poor souls are stuck on
|
||||
* Libevent 1.3e. */
|
||||
|
||||
#include "orconfig.h"
|
||||
#include "tor_compat.h"
|
||||
#include "compat_libevent.h"
|
||||
|
||||
#include "tor_util.h"
|
||||
#include "torlog.h"
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#include <event2/event.h>
|
||||
#include <event2/thread.h>
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
#include <event2/bufferevent.h>
|
||||
#endif
|
||||
#else
|
||||
#include <event.h>
|
||||
#endif
|
||||
|
||||
/** A number representing a version of Libevent.
|
||||
|
||||
This is a 4-byte number, with the first three bytes representing the
|
||||
major, minor, and patchlevel respectively of the library. The fourth
|
||||
byte is unused.
|
||||
|
||||
This is equivalent to the format of LIBEVENT_VERSION_NUMBER on Libevent
|
||||
2.0.1 or later. For versions of Libevent before 1.4.0, which followed the
|
||||
format of "1.0, 1.0a, 1.0b", we define 1.0 to be equivalent to 1.0.0, 1.0a
|
||||
to be equivalent to 1.0.1, and so on.
|
||||
*/
|
||||
typedef uint32_t le_version_t;
|
||||
|
||||
/** @{ */
|
||||
/** Macros: returns the number of a libevent version as a le_version_t */
|
||||
#define V(major, minor, patch) \
|
||||
(((major) << 24) | ((minor) << 16) | ((patch) << 8))
|
||||
#define V_OLD(major, minor, patch) \
|
||||
V((major), (minor), (patch)-'a'+1)
|
||||
/** @} */
|
||||
|
||||
/** Represetns a version of libevent so old we can't figure out what version
|
||||
* it is. */
|
||||
#define LE_OLD V(0,0,0)
|
||||
/** Represents a version of libevent so weird we can't figure out what version
|
||||
* it is. */
|
||||
#define LE_OTHER V(0,0,99)
|
||||
|
||||
#if 0
|
||||
static le_version_t tor_get_libevent_version(const char **v_out);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_SET_LOG_CALLBACK) || defined(RUNNING_DOXYGEN)
|
||||
/** A string which, if it appears in a libevent log, should be ignored. */
|
||||
static const char *suppress_msg = NULL;
|
||||
/** Callback function passed to event_set_log() so we can intercept
|
||||
* log messages from libevent. */
|
||||
static void
|
||||
libevent_logging_callback(int severity, const char *msg)
|
||||
{
|
||||
char buf[1024];
|
||||
size_t n;
|
||||
if (suppress_msg && strstr(msg, suppress_msg))
|
||||
return;
|
||||
n = strlcpy(buf, msg, sizeof(buf));
|
||||
if (n && n < sizeof(buf) && buf[n-1] == '\n') {
|
||||
buf[n-1] = '\0';
|
||||
}
|
||||
switch (severity) {
|
||||
case _EVENT_LOG_DEBUG:
|
||||
log_debug(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
|
||||
break;
|
||||
case _EVENT_LOG_MSG:
|
||||
log_info(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
|
||||
break;
|
||||
case _EVENT_LOG_WARN:
|
||||
log_warn(LD_NOCB|LD_GENERAL, "Warning from libevent: %s", buf);
|
||||
break;
|
||||
case _EVENT_LOG_ERR:
|
||||
log_err(LD_NOCB|LD_GENERAL, "Error from libevent: %s", buf);
|
||||
break;
|
||||
default:
|
||||
log_warn(LD_NOCB|LD_GENERAL, "Message [%d] from libevent: %s",
|
||||
severity, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/** Set hook to intercept log messages from libevent. */
|
||||
void
|
||||
configure_libevent_logging(void)
|
||||
{
|
||||
event_set_log_callback(libevent_logging_callback);
|
||||
}
|
||||
/** Ignore any libevent log message that contains <b>msg</b>. */
|
||||
void
|
||||
suppress_libevent_log_msg(const char *msg)
|
||||
{
|
||||
suppress_msg = msg;
|
||||
}
|
||||
#else
|
||||
void
|
||||
configure_libevent_logging(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
suppress_libevent_log_msg(const char *msg)
|
||||
{
|
||||
(void)msg;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EVENT2_EVENT_H
|
||||
/** Work-alike replacement for event_new() on pre-Libevent-2.0 systems. */
|
||||
struct event *
|
||||
tor_event_new(struct event_base *base, int sock, short what,
|
||||
void (*cb)(int, short, void *), void *arg)
|
||||
{
|
||||
struct event *e = tor_malloc_zero(sizeof(struct event));
|
||||
event_set(e, sock, what, cb, arg);
|
||||
if (! base)
|
||||
base = tor_libevent_get_base();
|
||||
event_base_set(base, e);
|
||||
return e;
|
||||
}
|
||||
/** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
|
||||
struct event *
|
||||
tor_evtimer_new(struct event_base *base,
|
||||
void (*cb)(int, short, void *), void *arg)
|
||||
{
|
||||
return tor_event_new(base, -1, 0, cb, arg);
|
||||
}
|
||||
/** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
|
||||
struct event *
|
||||
tor_evsignal_new(struct event_base * base, int sig,
|
||||
void (*cb)(int, short, void *), void *arg)
|
||||
{
|
||||
return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg);
|
||||
}
|
||||
/** Work-alike replacement for event_free() on pre-Libevent-2.0 systems. */
|
||||
void
|
||||
tor_event_free(struct event *ev)
|
||||
{
|
||||
event_del(ev);
|
||||
tor_free(ev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Global event base for use by the main thread. */
|
||||
struct event_base *the_event_base = NULL;
|
||||
|
||||
/* This is what passes for version detection on OSX. We set
|
||||
* MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
|
||||
* 10.4.0 (aka 1040). */
|
||||
#ifdef __APPLE__
|
||||
#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
||||
#define MACOSX_KQUEUE_IS_BROKEN \
|
||||
(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
|
||||
#else
|
||||
#define MACOSX_KQUEUE_IS_BROKEN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
static int using_iocp_bufferevents = 0;
|
||||
static void tor_libevent_set_tick_timeout(int msec_per_tick);
|
||||
|
||||
int
|
||||
tor_libevent_using_iocp_bufferevents(void)
|
||||
{
|
||||
return using_iocp_bufferevents;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Initialize the Libevent library and set up the event base. */
|
||||
void
|
||||
tor_libevent_initialize(tor_libevent_cfg *torcfg)
|
||||
{
|
||||
tor_assert(the_event_base == NULL);
|
||||
/* some paths below don't use torcfg, so avoid unused variable warnings */
|
||||
(void)torcfg;
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
{
|
||||
int attempts = 0;
|
||||
int using_threads;
|
||||
struct event_config *cfg;
|
||||
|
||||
retry:
|
||||
++attempts;
|
||||
using_threads = 0;
|
||||
cfg = event_config_new();
|
||||
tor_assert(cfg);
|
||||
|
||||
#if defined(_WIN32) && defined(USE_BUFFEREVENTS)
|
||||
if (! torcfg->disable_iocp) {
|
||||
evthread_use_windows_threads();
|
||||
event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP);
|
||||
using_iocp_bufferevents = 1;
|
||||
using_threads = 1;
|
||||
} else {
|
||||
using_iocp_bufferevents = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!using_threads) {
|
||||
/* Telling Libevent not to try to turn locking on can avoid a needless
|
||||
* socketpair() attempt. */
|
||||
event_config_set_flag(cfg, EVENT_BASE_FLAG_NOLOCK);
|
||||
}
|
||||
|
||||
#if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,0,7)
|
||||
if (torcfg->num_cpus > 0)
|
||||
event_config_set_num_cpus_hint(cfg, torcfg->num_cpus);
|
||||
#endif
|
||||
|
||||
#if LIBEVENT_VERSION_NUMBER >= V(2,0,9)
|
||||
/* We can enable changelist support with epoll, since we don't give
|
||||
* Libevent any dup'd fds. This lets us avoid some syscalls. */
|
||||
event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
|
||||
#endif
|
||||
|
||||
the_event_base = event_base_new_with_config(cfg);
|
||||
|
||||
event_config_free(cfg);
|
||||
|
||||
if (using_threads && the_event_base == NULL && attempts < 2) {
|
||||
/* This could be a socketpair() failure, which can happen sometimes on
|
||||
* windows boxes with obnoxious firewall rules. Downgrade and try
|
||||
* again. */
|
||||
#if defined(_WIN32) && defined(USE_BUFFEREVENTS)
|
||||
if (torcfg->disable_iocp == 0) {
|
||||
log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again "
|
||||
"with IOCP disabled.");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again.");
|
||||
}
|
||||
|
||||
torcfg->disable_iocp = 1;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
#else
|
||||
the_event_base = event_init();
|
||||
#endif
|
||||
|
||||
if (!the_event_base) {
|
||||
log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
|
||||
/* Making this a NOTICE for now so we can link bugs to a libevent versions
|
||||
* or methods better. */
|
||||
log_info(LD_GENERAL,
|
||||
"Initialized libevent version %s using method %s. Good.",
|
||||
event_get_version(), tor_libevent_get_method());
|
||||
#else
|
||||
log_notice(LD_GENERAL,
|
||||
"Initialized old libevent (version 1.0b or earlier).");
|
||||
log_warn(LD_GENERAL,
|
||||
"You have a *VERY* old version of libevent. It is likely to be buggy; "
|
||||
"please build Tor with a more recent version.");
|
||||
#endif
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
tor_libevent_set_tick_timeout(torcfg->msec_per_tick);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the current Libevent event base that we're set up to use. */
|
||||
struct event_base *
|
||||
tor_libevent_get_base(void)
|
||||
{
|
||||
return the_event_base;
|
||||
}
|
||||
|
||||
#ifndef HAVE_EVENT_BASE_LOOPEXIT
|
||||
/** Replacement for event_base_loopexit on some very old versions of Libevent
|
||||
* that we are not yet brave enough to deprecate. */
|
||||
int
|
||||
tor_event_base_loopexit(struct event_base *base, struct timeval *tv)
|
||||
{
|
||||
tor_assert(base == the_event_base);
|
||||
return event_loopexit(tv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return the name of the Libevent backend we're using. */
|
||||
const char *
|
||||
tor_libevent_get_method(void)
|
||||
{
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
return event_base_get_method(the_event_base);
|
||||
#elif defined(HAVE_EVENT_GET_METHOD)
|
||||
return event_get_method();
|
||||
#else
|
||||
return "<unknown>";
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the le_version_t for the version of libevent specified in the
|
||||
* string <b>v</b>. If the version is very new or uses an unrecognized
|
||||
* version, format, return LE_OTHER. */
|
||||
static le_version_t
|
||||
tor_decode_libevent_version(const char *v)
|
||||
{
|
||||
unsigned major, minor, patchlevel;
|
||||
char c, e, extra;
|
||||
int fields;
|
||||
|
||||
/* Try the new preferred "1.4.11-stable" format.
|
||||
* Also accept "1.4.14b-stable". */
|
||||
fields = tor_sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e);
|
||||
if (fields == 3 ||
|
||||
((fields == 4 || fields == 5 ) && (c == '-' || c == '_')) ||
|
||||
(fields == 5 && TOR_ISALPHA(c) && (e == '-' || e == '_'))) {
|
||||
return V(major,minor,patchlevel);
|
||||
}
|
||||
|
||||
/* Try the old "1.3e" format. */
|
||||
fields = tor_sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra);
|
||||
if (fields == 3 && TOR_ISALPHA(c)) {
|
||||
return V_OLD(major, minor, c);
|
||||
} else if (fields == 2) {
|
||||
return V(major, minor, 0);
|
||||
}
|
||||
|
||||
return LE_OTHER;
|
||||
}
|
||||
|
||||
/** Return an integer representing the binary interface of a Libevent library.
|
||||
* Two different versions with different numbers are sure not to be binary
|
||||
* compatible. Two different versions with the same numbers have a decent
|
||||
* chance of binary compatibility.*/
|
||||
static int
|
||||
le_versions_compatibility(le_version_t v)
|
||||
{
|
||||
if (v == LE_OTHER)
|
||||
return 0;
|
||||
if (v < V_OLD(1,0,'c'))
|
||||
return 1;
|
||||
else if (v < V(1,4,0))
|
||||
return 2;
|
||||
else if (v < V(1,4,99))
|
||||
return 3;
|
||||
else if (v < V(2,0,1))
|
||||
return 4;
|
||||
else /* Everything 2.0 and later should be compatible. */
|
||||
return 5;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/** Return the version number of the currently running version of Libevent.
|
||||
* See le_version_t for info on the format.
|
||||
*/
|
||||
static le_version_t
|
||||
tor_get_libevent_version(const char **v_out)
|
||||
{
|
||||
const char *v;
|
||||
le_version_t r;
|
||||
#if defined(HAVE_EVENT_GET_VERSION_NUMBER)
|
||||
v = event_get_version();
|
||||
r = event_get_version_number();
|
||||
#elif defined (HAVE_EVENT_GET_VERSION)
|
||||
v = event_get_version();
|
||||
r = tor_decode_libevent_version(v);
|
||||
#else
|
||||
v = "pre-1.0c";
|
||||
r = LE_OLD;
|
||||
#endif
|
||||
if (v_out)
|
||||
*v_out = v;
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return a string representation of the version of the currently running
|
||||
* version of Libevent. */
|
||||
const char *
|
||||
tor_libevent_get_version_str(void)
|
||||
{
|
||||
#ifdef HAVE_EVENT_GET_VERSION
|
||||
return event_get_version();
|
||||
#else
|
||||
return "pre-1.0c";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the current Libevent method and version to a list of versions
|
||||
* which are known not to work. Warn the user as appropriate.
|
||||
*/
|
||||
void
|
||||
tor_check_libevent_version(const char *m, int server,
|
||||
const char **badness_out)
|
||||
{
|
||||
(void) m;
|
||||
(void) server;
|
||||
*badness_out = NULL;
|
||||
}
|
||||
|
||||
#if defined(LIBEVENT_VERSION)
|
||||
#define HEADER_VERSION LIBEVENT_VERSION
|
||||
#elif defined(_EVENT_VERSION)
|
||||
#define HEADER_VERSION _EVENT_VERSION
|
||||
#endif
|
||||
|
||||
/** Return a string representation of the version of Libevent that was used
|
||||
* at compilation time. */
|
||||
const char *
|
||||
tor_libevent_get_header_version_str(void)
|
||||
{
|
||||
return HEADER_VERSION;
|
||||
}
|
||||
|
||||
/** See whether the headers we were built against differ from the library we
|
||||
* linked against so much that we're likely to crash. If so, warn the
|
||||
* user. */
|
||||
void
|
||||
tor_check_libevent_header_compatibility(void)
|
||||
{
|
||||
(void) le_versions_compatibility;
|
||||
(void) tor_decode_libevent_version;
|
||||
|
||||
/* In libevent versions before 2.0, it's hard to keep binary compatibility
|
||||
* between upgrades, and unpleasant to detect when the version we compiled
|
||||
* against is unlike the version we have linked against. Here's how. */
|
||||
#if defined(HEADER_VERSION) && defined(HAVE_EVENT_GET_VERSION)
|
||||
/* We have a header-file version and a function-call version. Easy. */
|
||||
if (strcmp(HEADER_VERSION, event_get_version())) {
|
||||
le_version_t v1, v2;
|
||||
int compat1 = -1, compat2 = -1;
|
||||
int verybad;
|
||||
v1 = tor_decode_libevent_version(HEADER_VERSION);
|
||||
v2 = tor_decode_libevent_version(event_get_version());
|
||||
compat1 = le_versions_compatibility(v1);
|
||||
compat2 = le_versions_compatibility(v2);
|
||||
|
||||
verybad = compat1 != compat2;
|
||||
|
||||
tor_log(verybad ? LOG_WARN : LOG_NOTICE,
|
||||
LD_GENERAL, "We were compiled with headers from version %s "
|
||||
"of Libevent, but we're using a Libevent library that says it's "
|
||||
"version %s.", HEADER_VERSION, event_get_version());
|
||||
if (verybad)
|
||||
log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
|
||||
else
|
||||
log_info(LD_GENERAL, "I think these versions are binary-compatible.");
|
||||
}
|
||||
#elif defined(HAVE_EVENT_GET_VERSION)
|
||||
/* event_get_version but no _EVENT_VERSION. We might be in 1.4.0-beta or
|
||||
earlier, where that's normal. To see whether we were compiled with an
|
||||
earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
|
||||
*/
|
||||
#ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
|
||||
/* The header files are 1.4.0-beta or later. If the version is not
|
||||
* 1.4.0-beta, we are incompatible. */
|
||||
{
|
||||
if (strcmp(event_get_version(), "1.4.0-beta")) {
|
||||
log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
|
||||
"Libevent 1.4.0-beta header files, whereas you have linked "
|
||||
"against Libevent %s. This will probably make Tor crash.",
|
||||
event_get_version());
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
|
||||
later, we're probably fine. */
|
||||
{
|
||||
const char *v = event_get_version();
|
||||
if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
|
||||
log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
|
||||
"Libevent header file from 1.3e or earlier, whereas you have "
|
||||
"linked against Libevent %s. This will probably make Tor "
|
||||
"crash.", event_get_version());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(HEADER_VERSION)
|
||||
#warn "_EVENT_VERSION is defined but not get_event_version(): Libevent is odd."
|
||||
#else
|
||||
/* Your libevent is ancient. */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
If possible, we're going to try to use Libevent's periodic timer support,
|
||||
since it does a pretty good job of making sure that periodic events get
|
||||
called exactly M seconds apart, rather than starting each one exactly M
|
||||
seconds after the time that the last one was run.
|
||||
*/
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#define HAVE_PERIODIC
|
||||
#define PERIODIC_FLAGS EV_PERSIST
|
||||
#else
|
||||
#define PERIODIC_FLAGS 0
|
||||
#endif
|
||||
|
||||
/** Represents a timer that's run every N microseconds by Libevent. */
|
||||
struct periodic_timer_t {
|
||||
/** Underlying event used to implement this periodic event. */
|
||||
struct event *ev;
|
||||
/** The callback we'll be invoking whenever the event triggers */
|
||||
void (*cb)(struct periodic_timer_t *, void *);
|
||||
/** User-supplied data for the callback */
|
||||
void *data;
|
||||
#ifndef HAVE_PERIODIC
|
||||
/** If Libevent doesn't know how to invoke events every N microseconds,
|
||||
* we'll need to remember the timeout interval here. */
|
||||
struct timeval tv;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Libevent callback to implement a periodic event. */
|
||||
static void
|
||||
periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
periodic_timer_t *timer = arg;
|
||||
(void) what;
|
||||
(void) fd;
|
||||
#ifndef HAVE_PERIODIC
|
||||
/** reschedule the event as needed. */
|
||||
event_add(timer->ev, &timer->tv);
|
||||
#endif
|
||||
timer->cb(timer, timer->data);
|
||||
}
|
||||
|
||||
/** Create and schedule a new timer that will run every <b>tv</b> in
|
||||
* the event loop of <b>base</b>. When the timer fires, it will
|
||||
* run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
|
||||
periodic_timer_t *
|
||||
periodic_timer_new(struct event_base *base,
|
||||
const struct timeval *tv,
|
||||
void (*cb)(periodic_timer_t *timer, void *data),
|
||||
void *data)
|
||||
{
|
||||
periodic_timer_t *timer;
|
||||
tor_assert(base);
|
||||
tor_assert(tv);
|
||||
tor_assert(cb);
|
||||
timer = tor_malloc_zero(sizeof(periodic_timer_t));
|
||||
if (!(timer->ev = tor_event_new(base, -1, PERIODIC_FLAGS,
|
||||
periodic_timer_cb, timer))) {
|
||||
tor_free(timer);
|
||||
return NULL;
|
||||
}
|
||||
timer->cb = cb;
|
||||
timer->data = data;
|
||||
#ifndef HAVE_PERIODIC
|
||||
memcpy(&timer->tv, tv, sizeof(struct timeval));
|
||||
#endif
|
||||
event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
|
||||
return timer;
|
||||
}
|
||||
|
||||
/** Stop and free a periodic timer */
|
||||
void
|
||||
periodic_timer_free(periodic_timer_t *timer)
|
||||
{
|
||||
if (!timer)
|
||||
return;
|
||||
tor_event_free(timer->ev);
|
||||
tor_free(timer);
|
||||
}
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
static const struct timeval *one_tick = NULL;
|
||||
/**
|
||||
* Return a special timeout to be passed whenever libevent's O(1) timeout
|
||||
* implementation should be used. Only use this when the timer is supposed
|
||||
* to fire after msec_per_tick ticks have elapsed.
|
||||
*/
|
||||
const struct timeval *
|
||||
tor_libevent_get_one_tick_timeout(void)
|
||||
{
|
||||
tor_assert(one_tick);
|
||||
return one_tick;
|
||||
}
|
||||
|
||||
/** Initialize the common timeout that we'll use to refill the buckets every
|
||||
* time a tick elapses. */
|
||||
static void
|
||||
tor_libevent_set_tick_timeout(int msec_per_tick)
|
||||
{
|
||||
struct event_base *base = tor_libevent_get_base();
|
||||
struct timeval tv;
|
||||
|
||||
tor_assert(! one_tick);
|
||||
tv.tv_sec = msec_per_tick / 1000;
|
||||
tv.tv_usec = (msec_per_tick % 1000) * 1000;
|
||||
one_tick = event_base_init_common_timeout(base, &tv);
|
||||
}
|
||||
|
||||
static struct bufferevent *
|
||||
tor_get_root_bufferevent(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent *u;
|
||||
while ((u = bufferevent_get_underlying(bev)) != NULL)
|
||||
bev = u;
|
||||
return bev;
|
||||
}
|
||||
|
||||
int
|
||||
tor_set_bufferevent_rate_limit(struct bufferevent *bev,
|
||||
struct ev_token_bucket_cfg *cfg)
|
||||
{
|
||||
return bufferevent_set_rate_limit(tor_get_root_bufferevent(bev), cfg);
|
||||
}
|
||||
|
||||
int
|
||||
tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
|
||||
struct bufferevent_rate_limit_group *g)
|
||||
{
|
||||
return bufferevent_add_to_rate_limit_group(tor_get_root_bufferevent(bev), g);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1)
|
||||
void
|
||||
tor_gettimeofday_cached(struct timeval *tv)
|
||||
{
|
||||
event_base_gettimeofday_cached(the_event_base, tv);
|
||||
}
|
||||
void
|
||||
tor_gettimeofday_cache_clear(void)
|
||||
{
|
||||
event_base_update_cache_time(the_event_base);
|
||||
}
|
||||
#else
|
||||
/** Cache the current hi-res time; the cache gets reset when libevent
|
||||
* calls us. */
|
||||
static struct timeval cached_time_hires = {0, 0};
|
||||
|
||||
/** Return a fairly recent view of the current time. */
|
||||
void
|
||||
tor_gettimeofday_cached(struct timeval *tv)
|
||||
{
|
||||
if (cached_time_hires.tv_sec == 0) {
|
||||
tor_gettimeofday(&cached_time_hires);
|
||||
}
|
||||
*tv = cached_time_hires;
|
||||
}
|
||||
|
||||
/** Reset the cached view of the current time, so that the next time we try
|
||||
* to learn it, we will get an up-to-date value. */
|
||||
void
|
||||
tor_gettimeofday_cache_clear(void)
|
||||
{
|
||||
cached_time_hires.tv_sec = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/* Copyright (c) 2009-2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#ifndef TOR_COMPAT_LIBEVENT_H
|
||||
#define TOR_COMPAT_LIBEVENT_H
|
||||
|
||||
#include "orconfig.h"
|
||||
|
||||
struct event;
|
||||
struct event_base;
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
struct bufferevent;
|
||||
struct ev_token_bucket_cfg;
|
||||
struct bufferevent_rate_limit_group;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#include <event2/util.h>
|
||||
#elif !defined(EVUTIL_SOCKET_DEFINED)
|
||||
#define EVUTIL_SOCKET_DEFINED
|
||||
#define evutil_socket_t int
|
||||
#endif
|
||||
|
||||
void configure_libevent_logging(void);
|
||||
void suppress_libevent_log_msg(const char *msg);
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#define tor_event_new event_new
|
||||
#define tor_evtimer_new evtimer_new
|
||||
#define tor_evsignal_new evsignal_new
|
||||
#define tor_event_free event_free
|
||||
#define tor_evdns_add_server_port(sock, tcp, cb, data) \
|
||||
evdns_add_server_port_with_base(tor_libevent_get_base(), \
|
||||
(sock),(tcp),(cb),(data));
|
||||
|
||||
#else
|
||||
struct event *tor_event_new(struct event_base * base, evutil_socket_t sock,
|
||||
short what, void (*cb)(evutil_socket_t, short, void *), void *arg);
|
||||
struct event *tor_evtimer_new(struct event_base * base,
|
||||
void (*cb)(evutil_socket_t, short, void *), void *arg);
|
||||
struct event *tor_evsignal_new(struct event_base * base, int sig,
|
||||
void (*cb)(evutil_socket_t, short, void *), void *arg);
|
||||
void tor_event_free(struct event *ev);
|
||||
#define tor_evdns_add_server_port evdns_add_server_port
|
||||
#endif
|
||||
|
||||
typedef struct periodic_timer_t periodic_timer_t;
|
||||
|
||||
periodic_timer_t *periodic_timer_new(struct event_base *base,
|
||||
const struct timeval *tv,
|
||||
void (*cb)(periodic_timer_t *timer, void *data),
|
||||
void *data);
|
||||
void periodic_timer_free(periodic_timer_t *);
|
||||
|
||||
#ifdef HAVE_EVENT_BASE_LOOPEXIT
|
||||
#define tor_event_base_loopexit event_base_loopexit
|
||||
#else
|
||||
struct timeval;
|
||||
int tor_event_base_loopexit(struct event_base *base, struct timeval *tv);
|
||||
#endif
|
||||
|
||||
/** Defines a configuration for using libevent with Tor: passed as an argument
|
||||
* to tor_libevent_initialize() to describe how we want to set up. */
|
||||
typedef struct tor_libevent_cfg {
|
||||
/** Flag: if true, disable IOCP (assuming that it could be enabled). */
|
||||
int disable_iocp;
|
||||
/** How many CPUs should we use (relevant only with IOCP). */
|
||||
int num_cpus;
|
||||
/** How many milliseconds should we allow between updating bandwidth limits?
|
||||
* (relevant only with bufferevents). */
|
||||
int msec_per_tick;
|
||||
} tor_libevent_cfg;
|
||||
|
||||
void tor_libevent_initialize(tor_libevent_cfg *cfg);
|
||||
struct event_base *tor_libevent_get_base(void);
|
||||
const char *tor_libevent_get_method(void);
|
||||
void tor_check_libevent_version(const char *m, int server,
|
||||
const char **badness_out);
|
||||
void tor_check_libevent_header_compatibility(void);
|
||||
const char *tor_libevent_get_version_str(void);
|
||||
const char *tor_libevent_get_header_version_str(void);
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
const struct timeval *tor_libevent_get_one_tick_timeout(void);
|
||||
int tor_libevent_using_iocp_bufferevents(void);
|
||||
int tor_set_bufferevent_rate_limit(struct bufferevent *bev,
|
||||
struct ev_token_bucket_cfg *cfg);
|
||||
int tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
|
||||
struct bufferevent_rate_limit_group *g);
|
||||
#endif
|
||||
|
||||
void tor_gettimeofday_cached(struct timeval *tv);
|
||||
void tor_gettimeofday_cache_clear(void);
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user