forked from bitcoinj/bitcoinj
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changes to support connecting to .onion addresses:
+ PeerAddress detects .onion and serializes/deserializes them using the onioncat format, which is also used by bitcoin-core, btcd, and probably others. + added some new DNS seeds from bitcoin-core + PeerGroup now listens for "addr" protocol messages and adds new peers to inactive list. This enables peer discovery beyond what is found by DNS and hard-coded seeds. Discovered peers are not presently persisted to disk. + Beginnings of a class for validating that peer addresses are routable. + Catch PeerDiscoveryException during getPeers call. avoids stack trace when all DNS lookups timeout
- Loading branch information
Showing
8 changed files
with
465 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package org.bitcoinj.net; | ||
|
||
import org.bitcoinj.utils.CIDRUtils; | ||
|
||
import java.net.InetAddress; | ||
import java.net.UnknownHostException; | ||
|
||
/** | ||
* Created by danda on 1/12/17. | ||
*/ | ||
public class AddressChecker { | ||
|
||
private CIDRUtils onionCatNet; | ||
private CIDRUtils rfc4193Net; | ||
|
||
public AddressChecker() { | ||
|
||
// Note: this is borrowed/ported from btcd (written in go). | ||
|
||
// btcd has many more rules that are probably important and should be | ||
// implemented in this class, but for now we only care about onion | ||
// addresses for onioncat (ipv6) encoding/decoding. | ||
|
||
// onionCatNet defines the IPv6 address block used to support Tor. | ||
// bitcoind encodes a .onion address as a 16 byte number by decoding the | ||
// address prior to the .onion (i.e. the key hash) base32 into a ten | ||
// byte number. It then stores the first 6 bytes of the address as | ||
// 0xfd, 0x87, 0xd8, 0x7e, 0xeb, 0x43. | ||
// | ||
// This is the same range used by OnionCat, which is part part of the | ||
// RFC4193 unique local IPv6 range. | ||
// | ||
// In summary the format is: | ||
// { magic 6 bytes, 10 bytes base32 decode of key hash } | ||
onionCatNet = new CIDRUtils("fd87:d87e:eb43::", 48); | ||
|
||
// rfc4193Net specifies the IPv6 unique local address block as defined | ||
// by RFC4193 (FC00::/7). | ||
rfc4193Net = new CIDRUtils("FC00::", 7); | ||
} | ||
|
||
// IsValid returns whether or not the passed address is valid. The address is | ||
// considered invalid under the following circumstances: | ||
// IPv4: It is either a zero or all bits set address. | ||
// IPv6: It is either a zero or RFC3849 documentation address. | ||
public boolean IsValid(InetAddress addr) { | ||
// todo: port/implement. | ||
|
||
// IsUnspecified returns if address is 0, so only all bits set, and | ||
// RFC3849 need to be explicitly checked. | ||
|
||
// return na.IP != nil && !(na.IP.IsUnspecified() || | ||
// na.IP.Equal(net.IPv4bcast)) | ||
|
||
return true; | ||
} | ||
|
||
// IsOnionCatTor returns whether or not the passed address is in the IPv6 range | ||
// used by bitcoin to support Tor (fd87:d87e:eb43::/48). Note that this range | ||
// is the same range used by OnionCat, which is part of the RFC4193 unique local | ||
// IPv6 range. | ||
public boolean IsOnionCatTor(InetAddress addr) { | ||
return onionCatNet.isInRange(addr); | ||
} | ||
|
||
// IsRFC4193 returns whether or not the passed address is part of the IPv6 | ||
// unique local range as defined by RFC4193 (FC00::/7). | ||
public boolean IsRFC4193(InetAddress addr) { | ||
return rfc4193Net.isInRange(addr); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.bitcoinj.net; | ||
|
||
import org.bitcoinj.utils.Base32; | ||
|
||
import java.net.InetAddress; | ||
import java.net.InetSocketAddress; | ||
import java.net.UnknownHostException; | ||
import java.util.Arrays; | ||
|
||
|
||
/** | ||
* Created by danda on 1/12/17. | ||
*/ | ||
public class OnionCat { | ||
|
||
/** Converts a .onion address to onioncat format | ||
* | ||
* @param hostname | ||
* @return | ||
*/ | ||
public static byte[] onionHostToIPV6Bytes(String hostname) { | ||
String needle = ".onion"; | ||
if( hostname.endsWith(needle) ) { | ||
hostname = hostname.substring(0,hostname.length() - needle.length()); | ||
} | ||
byte[] prefix = new byte[] {(byte)0xfd, (byte)0x87, (byte)0xd8, (byte)0x7e, (byte)0xeb, (byte)0x43}; | ||
byte[] onionaddr = Base32.base32Decode(hostname); | ||
byte[] ipBytes = new byte[prefix.length + onionaddr.length]; | ||
System.arraycopy(prefix, 0, ipBytes, 0, prefix.length); | ||
System.arraycopy(onionaddr, 0, ipBytes, prefix.length, onionaddr.length); | ||
|
||
return ipBytes; | ||
} | ||
|
||
public static InetAddress onionHostToInetAddress(String hostname) throws UnknownHostException { | ||
return InetAddress.getByAddress(onionHostToIPV6Bytes(hostname)); | ||
} | ||
|
||
public static InetSocketAddress onionHostToInetSocketAddress(String hostname, int port) throws UnknownHostException { | ||
return new InetSocketAddress( onionHostToInetAddress(hostname), port); | ||
} | ||
|
||
|
||
/** Converts an IPV6 onioncat encoded address to a hostname | ||
* | ||
* @param bytes | ||
* @return | ||
*/ | ||
public static String IPV6BytesToOnionHost( byte[] bytes) { | ||
String base32 = Base32.base32Encode( Arrays.copyOfRange(bytes, 6, 16) ); | ||
return base32.toLowerCase() + ".onion"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.