mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +01:00
Rework tor exceptions to be more useful (#4854)
This commit is contained in:
parent
89a4c9e13e
commit
63b05e398a
2 changed files with 116 additions and 39 deletions
|
@ -73,7 +73,8 @@ class Socks5Connection(
|
|||
context.parent ! Socks5Connected(connectedAddress)
|
||||
isConnected = true
|
||||
case Failure(err) =>
|
||||
logger.error(s"Tor connection request failed to $target", err)
|
||||
logger.error(
|
||||
s"Tor connection request failed to $target errMsg=${err.toString}")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,18 +126,6 @@ object Socks5Connection {
|
|||
val NoAuth: Byte = 0x00
|
||||
val PasswordAuth: Byte = 0x02
|
||||
|
||||
val connectErrors: Map[Byte, String] = Map[Byte, String](
|
||||
(0x00, "Request granted"),
|
||||
(0x01, "General failure"),
|
||||
(0x02, "Connection not allowed by ruleset"),
|
||||
(0x03, "Network unreachable"),
|
||||
(0x04, "Host unreachable"),
|
||||
(0x05, "Connection refused by destination host"),
|
||||
(0x06, "TTL expired"),
|
||||
(0x07, "Command not supported / protocol error"),
|
||||
(0x08, "Address type not supported")
|
||||
)
|
||||
|
||||
def socks5Greeting(passwordAuth: Boolean): ByteString = ByteString(
|
||||
0x05, // SOCKS version
|
||||
0x01, // number of authentication methods supported
|
||||
|
@ -213,34 +202,39 @@ object Socks5Connection {
|
|||
}
|
||||
}
|
||||
|
||||
def parseConnectedAddress(data: ByteString): InetSocketAddress = {
|
||||
def tryParseConnectedAddress(data: ByteString): Try[InetSocketAddress] = {
|
||||
if (data(0) != 0x05) {
|
||||
throw Socks5Error("Invalid proxy version")
|
||||
} else {
|
||||
val status = data(1)
|
||||
if (status != 0) {
|
||||
val errMsg =
|
||||
connectErrors.getOrElse(status, s"Unknown SOCKS5 error $status")
|
||||
throw Socks5Error(errMsg + s" data=$data")
|
||||
}
|
||||
val connectionError = TorConnectionError.fromByte(status)
|
||||
Failure(connectionError.exn)
|
||||
} else {
|
||||
data(3) match {
|
||||
case 0x01 =>
|
||||
val ip = Array(data(4), data(5), data(6), data(7))
|
||||
val port = data(8).toInt << 8 | data(9)
|
||||
val socket =
|
||||
new InetSocketAddress(InetAddress.getByAddress(ip), port)
|
||||
Success(socket)
|
||||
case 0x03 =>
|
||||
val len = data(4)
|
||||
val start = 5
|
||||
val end = start + len
|
||||
val domain = data.slice(start, end).utf8String
|
||||
val port = data(end).toInt << 8 | data(end + 1)
|
||||
new InetSocketAddress(domain, port)
|
||||
val socket = new InetSocketAddress(domain, port)
|
||||
Success(socket)
|
||||
case 0x04 =>
|
||||
val ip = Array.ofDim[Byte](16)
|
||||
data.copyToArray(ip, 4, 4 + ip.length)
|
||||
val port = data(4 + ip.length).toInt << 8 | data(4 + ip.length + 1)
|
||||
val socket =
|
||||
new InetSocketAddress(InetAddress.getByAddress(ip), port)
|
||||
case b => throw Socks5Error(s"Unrecognized address type $b")
|
||||
Success(socket)
|
||||
case b => Failure(Socks5Error(s"Unrecognized address type $b"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,9 +244,6 @@ object Socks5Connection {
|
|||
|
||||
def tryParseAuth(data: ByteString): Try[Boolean] = Try(parseAuth(data))
|
||||
|
||||
def tryParseConnectedAddress(data: ByteString): Try[InetSocketAddress] = Try(
|
||||
parseConnectedAddress(data))
|
||||
|
||||
}
|
||||
|
||||
case class Socks5ProxyParams(
|
||||
|
|
86
tor/src/main/scala/org/bitcoins/tor/TorConnectionError.scala
Normal file
86
tor/src/main/scala/org/bitcoins/tor/TorConnectionError.scala
Normal file
|
@ -0,0 +1,86 @@
|
|||
package org.bitcoins.tor
|
||||
|
||||
sealed trait TorConnectionError {
|
||||
def prefix: Byte
|
||||
|
||||
def exn: RuntimeException = new RuntimeException(toString)
|
||||
}
|
||||
|
||||
object TorConnectionError {
|
||||
|
||||
val connectErrors: Map[Byte, String] = Map[Byte, String](
|
||||
(0x00, "Request granted"),
|
||||
(0x01, "General failure"),
|
||||
(0x02, "Connection not allowed by ruleset"),
|
||||
(0x03, "Network unreachable"),
|
||||
(0x04, "Host unreachable"),
|
||||
(0x05, "Connection refused by destination host"),
|
||||
(0x06, "TTL expired"),
|
||||
(0x07, "Command not supported / protocol error"),
|
||||
(0x08, "Address type not supported")
|
||||
)
|
||||
|
||||
private val all: Vector[TorConnectionError] = Vector(
|
||||
RequestGranted,
|
||||
GeneralFailure,
|
||||
ConnectionNotAllowed,
|
||||
NetworkUnreachable,
|
||||
HostUnreachable,
|
||||
ConnectionRefusedByDestination,
|
||||
TTLExpired,
|
||||
CommandNotSupportedOrProtocolError,
|
||||
AddressTypeNotSupported
|
||||
)
|
||||
|
||||
def fromByte(byte: Byte): TorConnectionError = {
|
||||
fromByteOpt(byte) match {
|
||||
case Some(err) => err
|
||||
case None =>
|
||||
sys.error(s"Could not find tor connection error by prefix=$byte")
|
||||
}
|
||||
}
|
||||
|
||||
def fromByteOpt(byte: Byte): Option[TorConnectionError] = {
|
||||
all.find(_.prefix == byte)
|
||||
}
|
||||
|
||||
case object RequestGranted extends TorConnectionError {
|
||||
override val prefix: Byte = 0.toByte
|
||||
}
|
||||
|
||||
case object GeneralFailure extends TorConnectionError {
|
||||
override val prefix: Byte = 1.toByte
|
||||
|
||||
override def toString: String =
|
||||
s"General failure, this likely means tor timed out when trying to connect. Try using telnet to reproduce error."
|
||||
}
|
||||
|
||||
case object ConnectionNotAllowed extends TorConnectionError {
|
||||
override val prefix: Byte = 0x02.toByte
|
||||
override val toString: String = "Connection not allowed by ruleset"
|
||||
}
|
||||
|
||||
case object NetworkUnreachable extends TorConnectionError {
|
||||
override val prefix: Byte = 0x03.toByte
|
||||
}
|
||||
|
||||
case object HostUnreachable extends TorConnectionError {
|
||||
override val prefix: Byte = 0x04.toByte
|
||||
}
|
||||
|
||||
case object ConnectionRefusedByDestination extends TorConnectionError {
|
||||
override val prefix: Byte = 0x05.toByte
|
||||
}
|
||||
|
||||
case object TTLExpired extends TorConnectionError {
|
||||
override val prefix: Byte = 0x06.toByte
|
||||
}
|
||||
|
||||
case object CommandNotSupportedOrProtocolError extends TorConnectionError {
|
||||
override val prefix: Byte = 0x07.toByte
|
||||
}
|
||||
|
||||
case object AddressTypeNotSupported extends TorConnectionError {
|
||||
override val prefix: Byte = 0x08.toByte
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue