mirror of https://github.com/lukechilds/komodo.git
Giel van Schijndel
13 years ago
37 changed files with 898 additions and 205 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,96 @@ |
|||
TOR SUPPORT IN BITCOIN |
|||
====================== |
|||
|
|||
It is possible to run Bitcoin as a Tor hidden service, and connect to such services. |
|||
|
|||
The following assumes you have a Tor proxy running on port 9050. Many distributions |
|||
default to having a SOCKS proxy listening on port 9050, but others may not. |
|||
In particular, the Tor Browser Bundle defaults to listening on a random port. See |
|||
https://www.torproject.org/docs/faq.html.en#TBBSocksPort for how to properly |
|||
configure Tor. |
|||
|
|||
|
|||
1. Run bitcoin behind a Tor proxy |
|||
--------------------------------- |
|||
|
|||
The first step is running Bitcoin behind a Tor proxy. This will already make all |
|||
outgoing connections be anonimized, but more is possible. |
|||
|
|||
-socks=5 SOCKS5 supports connecting-to-hostname, which can be used instead |
|||
of doing a (leaking) local DNS lookup. SOCKS5 is the default, |
|||
but SOCKS4 does not support this. (SOCKS4a does, but isn't |
|||
implemented). |
|||
|
|||
-proxy=ip:port Set the proxy server. If SOCKS5 is selected (default), this proxy |
|||
server will be used to try to reach .onion addresses as well. |
|||
|
|||
-tor=ip:port Set the proxy server to use for tor hidden services. You do not |
|||
need to set this if it's the same as -proxy. You can use -notor |
|||
to explicitly disable access to hidden service. |
|||
|
|||
-dnsseed DNS seeds are not resolved directly when a SOCKS5 proxy server is |
|||
set. Rather, a short-lived proxy connection to the dns seed |
|||
hostname is attempted, and peer addresses are requested. |
|||
|
|||
-listen When using -proxy, listening is disabled by default. If you want |
|||
to run a hidden service (see next section), you'll need to enable |
|||
it explicitly. |
|||
|
|||
-connect=X When behing a Tor proxy, you can specify .onion addresses instead |
|||
-addnode=X of IP addresses or hostnames in these parameters. It requires |
|||
-seednode=X SOCKS5. In Tor mode, such addresses can also be exchanged with |
|||
other P2P nodes. |
|||
|
|||
In a typical situation, this suffices to run behind a Tor proxy: |
|||
|
|||
./bitcoin -proxy=127.0.0.1:9050 |
|||
|
|||
|
|||
2. Run a bitcoin hidden server |
|||
------------------------------ |
|||
|
|||
If you configure your Tor system accordingly, it is possible to make your node also |
|||
reachable from the Tor network. Add these lines to your /etc/tor/torrc (or equivalent |
|||
config file): |
|||
|
|||
HiddenServiceDir /var/lib/tor/bitcoin-service/ |
|||
HiddenServicePort 8333 127.0.0.1:8333 |
|||
|
|||
The directory can be different of course, but (both) 8333's should be equal to your |
|||
bitcoind's P2P listen port (8333 by default). |
|||
|
|||
-externalip=X You can tell bitcoin about its publically reachable address using |
|||
this option, and this can be a .onion address. Given the above |
|||
configuration, you can find your onion address in |
|||
/var/lib/tor/bitcoin-service/hostname. Onion addresses are given |
|||
preference for your node to advertize itself with, for connections |
|||
coming from unroutable addresses (such as 127.0.0.1, where the |
|||
Tor proxy typically runs). |
|||
|
|||
-listen You'll need to enable listening for incoming connections, as this |
|||
is off by default behind a proxy. |
|||
|
|||
-discover When -externalip is specified, no attempt is made to discover local |
|||
IPv4 or IPv6 addresses. If you want to run a dual stack, reachable |
|||
from both Tor and IPv4 (or IPv6), you'll need to either pass your |
|||
other addresses using -externalip, or explicitly enable -discover. |
|||
Note that both addresses of a dual-stack system may be easily |
|||
linkable using traffic analysis. |
|||
|
|||
In a typical situation, where you're only reachable via Tor, this should suffice: |
|||
|
|||
./bitcoind -proxy=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -listen |
|||
|
|||
(obviously replace the Onion address with your own). If you don't care too much |
|||
about hiding your node, and want to be reachable on IPv4 as well, additionally |
|||
specify: |
|||
|
|||
./bitcoind ... -discover |
|||
|
|||
and open port 8333 on your firewall (or use -upnp). |
|||
|
|||
If you only want to use Tor to reach onion addresses, but not use it as a proxy |
|||
for normal IPv4/IPv6 communication, use: |
|||
|
|||
./bitcoin -tor=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover |
|||
|
@ -0,0 +1,20 @@ |
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
#include "util.h" |
|||
|
|||
BOOST_AUTO_TEST_SUITE(base32_tests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(base32_testvectors) |
|||
{ |
|||
static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; |
|||
static const std::string vstrOut[] = {"","my======","mzxq====","mzxw6===","mzxw6yq=","mzxw6ytb","mzxw6ytboi======"}; |
|||
for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++) |
|||
{ |
|||
std::string strEnc = EncodeBase32(vstrIn[i]); |
|||
BOOST_CHECK(strEnc == vstrOut[i]); |
|||
std::string strDec = DecodeBase32(vstrOut[i]); |
|||
BOOST_CHECK(strDec == vstrIn[i]); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -0,0 +1,125 @@ |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <limits> |
|||
|
|||
#include "bignum.h" |
|||
#include "util.h" |
|||
|
|||
BOOST_AUTO_TEST_SUITE(bignum_tests) |
|||
|
|||
// Unfortunately there's no standard way of preventing a function from being
|
|||
// inlined, so we define a macro for it.
|
|||
//
|
|||
// You should use it like this:
|
|||
// NOINLINE void function() {...}
|
|||
#if defined(__GNUC__) |
|||
// This also works and will be defined for any compiler implementing gcc
|
|||
// extensions, such as clang and icc.
|
|||
#define NOINLINE __attribute__((noinline)) |
|||
#elif defined(_MSC_VER) |
|||
#define NOINLINE __declspec(noinline) |
|||
#else |
|||
// We give out a warning because it impacts the correctness of one bignum test.
|
|||
#warning You should define NOINLINE for your compiler. |
|||
#define NOINLINE |
|||
#endif |
|||
|
|||
// For the following test case, it is useful to use additional tools.
|
|||
//
|
|||
// The simplest one to use is the compiler flag -ftrapv, which detects integer
|
|||
// overflows and similar errors. However, due to optimizations and compilers
|
|||
// taking advantage of undefined behavior sometimes it may not actually detect
|
|||
// anything.
|
|||
//
|
|||
// You can also use compiler-based stack protection to possibly detect possible
|
|||
// stack buffer overruns.
|
|||
//
|
|||
// For more accurate diagnostics, you can use an undefined arithmetic operation
|
|||
// detector such as the clang-based tool:
|
|||
//
|
|||
// "IOC: An Integer Overflow Checker for C/C++"
|
|||
//
|
|||
// Available at: http://embed.cs.utah.edu/ioc/
|
|||
//
|
|||
// It might also be useful to use Google's AddressSanitizer to detect
|
|||
// stack buffer overruns, which valgrind can't currently detect.
|
|||
|
|||
// Let's force this code not to be inlined, in order to actually
|
|||
// test a generic version of the function. This increases the chance
|
|||
// that -ftrapv will detect overflows.
|
|||
NOINLINE void mysetint64(CBigNum& num, int64 n) |
|||
{ |
|||
num.setint64(n); |
|||
} |
|||
|
|||
// For each number, we do 2 tests: one with inline code, then we reset the
|
|||
// value to 0, then the second one with a non-inlined function.
|
|||
BOOST_AUTO_TEST_CASE(bignum_setint64) |
|||
{ |
|||
int64 n; |
|||
|
|||
{ |
|||
n = 0; |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
} |
|||
{ |
|||
n = 1; |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "1"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "1"); |
|||
} |
|||
{ |
|||
n = -1; |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "-1"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "-1"); |
|||
} |
|||
{ |
|||
n = 5; |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "5"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "5"); |
|||
} |
|||
{ |
|||
n = -5; |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "-5"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "-5"); |
|||
} |
|||
{ |
|||
n = std::numeric_limits<int64>::min(); |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "-9223372036854775808"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "-9223372036854775808"); |
|||
} |
|||
{ |
|||
n = std::numeric_limits<int64>::max(); |
|||
CBigNum num(n); |
|||
BOOST_CHECK(num.ToString() == "9223372036854775807"); |
|||
num.setulong(0); |
|||
BOOST_CHECK(num.ToString() == "0"); |
|||
mysetint64(num, n); |
|||
BOOST_CHECK(num.ToString() == "9223372036854775807"); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -0,0 +1,102 @@ |
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
|
|||
#include "netbase.h" |
|||
|
|||
using namespace std; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(netbase_tests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(netbase_networks) |
|||
{ |
|||
BOOST_CHECK(CNetAddr("127.0.0.1").GetNetwork() == NET_UNROUTABLE); |
|||
BOOST_CHECK(CNetAddr("::1").GetNetwork() == NET_UNROUTABLE); |
|||
BOOST_CHECK(CNetAddr("8.8.8.8").GetNetwork() == NET_IPV4); |
|||
BOOST_CHECK(CNetAddr("2001::8888").GetNetwork() == NET_IPV6); |
|||
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(netbase_properties) |
|||
{ |
|||
BOOST_CHECK(CNetAddr("127.0.0.1").IsIPv4()); |
|||
BOOST_CHECK(CNetAddr("::FFFF:192.168.1.1").IsIPv4()); |
|||
BOOST_CHECK(CNetAddr("::1").IsIPv6()); |
|||
BOOST_CHECK(CNetAddr("10.0.0.1").IsRFC1918()); |
|||
BOOST_CHECK(CNetAddr("192.168.1.1").IsRFC1918()); |
|||
BOOST_CHECK(CNetAddr("172.31.255.255").IsRFC1918()); |
|||
BOOST_CHECK(CNetAddr("2001:0DB8::").IsRFC3849()); |
|||
BOOST_CHECK(CNetAddr("169.254.1.1").IsRFC3927()); |
|||
BOOST_CHECK(CNetAddr("2002::1").IsRFC3964()); |
|||
BOOST_CHECK(CNetAddr("FC00::").IsRFC4193()); |
|||
BOOST_CHECK(CNetAddr("2001::2").IsRFC4380()); |
|||
BOOST_CHECK(CNetAddr("2001:10::").IsRFC4843()); |
|||
BOOST_CHECK(CNetAddr("FE80::").IsRFC4862()); |
|||
BOOST_CHECK(CNetAddr("64:FF9B::").IsRFC6052()); |
|||
BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").IsTor()); |
|||
BOOST_CHECK(CNetAddr("127.0.0.1").IsLocal()); |
|||
BOOST_CHECK(CNetAddr("::1").IsLocal()); |
|||
BOOST_CHECK(CNetAddr("8.8.8.8").IsRoutable()); |
|||
BOOST_CHECK(CNetAddr("2001::1").IsRoutable()); |
|||
BOOST_CHECK(CNetAddr("127.0.0.1").IsValid()); |
|||
} |
|||
|
|||
bool static TestSplitHost(string test, string host, int port) |
|||
{ |
|||
string hostOut; |
|||
int portOut = -1; |
|||
SplitHostPort(test, portOut, hostOut); |
|||
return hostOut == host && port == portOut; |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(netbase_splithost) |
|||
{ |
|||
BOOST_CHECK(TestSplitHost("www.bitcoin.org", "www.bitcoin.org", -1)); |
|||
BOOST_CHECK(TestSplitHost("[www.bitcoin.org]", "www.bitcoin.org", -1)); |
|||
BOOST_CHECK(TestSplitHost("www.bitcoin.org:80", "www.bitcoin.org", 80)); |
|||
BOOST_CHECK(TestSplitHost("[www.bitcoin.org]:80", "www.bitcoin.org", 80)); |
|||
BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", -1)); |
|||
BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333)); |
|||
BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", -1)); |
|||
BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333)); |
|||
BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", -1)); |
|||
BOOST_CHECK(TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333)); |
|||
BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333)); |
|||
BOOST_CHECK(TestSplitHost("::8333", "::8333", -1)); |
|||
BOOST_CHECK(TestSplitHost(":8333", "", 8333)); |
|||
BOOST_CHECK(TestSplitHost("[]:8333", "", 8333)); |
|||
BOOST_CHECK(TestSplitHost("", "", -1)); |
|||
} |
|||
|
|||
bool static TestParse(string src, string canon) |
|||
{ |
|||
CService addr; |
|||
if (!LookupNumeric(src.c_str(), addr, 65535)) |
|||
return canon == ""; |
|||
return canon == addr.ToString(); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) |
|||
{ |
|||
BOOST_CHECK(TestParse("127.0.0.1", "127.0.0.1:65535")); |
|||
BOOST_CHECK(TestParse("127.0.0.1:8333", "127.0.0.1:8333")); |
|||
BOOST_CHECK(TestParse("::ffff:127.0.0.1", "127.0.0.1:65535")); |
|||
BOOST_CHECK(TestParse("::", "[::]:65535")); |
|||
BOOST_CHECK(TestParse("[::]:8333", "[::]:8333")); |
|||
BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); |
|||
BOOST_CHECK(TestParse(":::", "")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(onioncat_test) |
|||
{ |
|||
// values from http://www.cypherpunk.at/onioncat/wiki/OnionCat
|
|||
CNetAddr addr1("5wyqrzbvrdsumnok.onion"); |
|||
CNetAddr addr2("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca"); |
|||
BOOST_CHECK(addr1 == addr2); |
|||
BOOST_CHECK(addr1.IsTor()); |
|||
BOOST_CHECK(addr1.ToStringIP() == "5wyqrzbvrdsumnok.onion"); |
|||
BOOST_CHECK(addr1.IsRoutable()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
Loading…
Reference in new issue