Merge bitcoin/bitcoin#32200: net: Add Tor extended SOCKS5 error codes

b639417b39 net: Add Tor extended SOCKS5 error codes (laanwj)

Pull request description:

  Add support for reporting Tor extended SOCKS5 error codes as defined here:

  - https://spec.torproject.org/socks-extensions.html#extended-error-codes
  - https://gitlab.torproject.org/tpo/core/arti/-/blob/main/crates/tor-socksproto/src/msg.rs?ref_type=heads#L183

  These give a more direct indication of the problem in case of errors connecting to hidden services, for example:
  ```
  2025-04-02T10:34:13Z [net] Socks5() connect to [elided].onion:8333 failed: onion service descriptor can not be found
  ```

  In the C Tor implementation, to get these one should set the "ExtendedErrors" flag on the "SocksPort" definition, introduced in version 0.4.3.1.

  In Arti, extended error codes are always enabled.

  Also, report the raw error code in case of unknown reply values.

ACKs for top commit:
  1440000bytes:
    utACK b639417b39
  w0xlt:
    utACK b639417b39
  pablomartin4btc:
    utACK b639417b39

Tree-SHA512: b30e65cb0f5c9183701373b0ee64cdec40680a3de1a1a365b006538c4d0b7ca8a047d7c6f81a7f5b8a36bae3a20b47a4c2a9850423c7034866e3837fa8fdbfe2
This commit is contained in:
Ryan Ofsky 2025-04-08 16:23:00 -04:00
commit 873a45fba0
No known key found for this signature in database
GPG key ID: 46800E30FC748A66

View file

@ -266,17 +266,25 @@ enum SOCKS5Command: uint8_t {
UDP_ASSOCIATE = 0x03 UDP_ASSOCIATE = 0x03
}; };
/** Values defined for REP in RFC1928 */ /** Values defined for REP in RFC1928 and https://spec.torproject.org/socks-extensions.html */
enum SOCKS5Reply: uint8_t { enum SOCKS5Reply: uint8_t {
SUCCEEDED = 0x00, //!< Succeeded SUCCEEDED = 0x00, //!< RFC1928: Succeeded
GENFAILURE = 0x01, //!< General failure GENFAILURE = 0x01, //!< RFC1928: General failure
NOTALLOWED = 0x02, //!< Connection not allowed by ruleset NOTALLOWED = 0x02, //!< RFC1928: Connection not allowed by ruleset
NETUNREACHABLE = 0x03, //!< Network unreachable NETUNREACHABLE = 0x03, //!< RFC1928: Network unreachable
HOSTUNREACHABLE = 0x04, //!< Network unreachable HOSTUNREACHABLE = 0x04, //!< RFC1928: Network unreachable
CONNREFUSED = 0x05, //!< Connection refused CONNREFUSED = 0x05, //!< RFC1928: Connection refused
TTLEXPIRED = 0x06, //!< TTL expired TTLEXPIRED = 0x06, //!< RFC1928: TTL expired
CMDUNSUPPORTED = 0x07, //!< Command not supported CMDUNSUPPORTED = 0x07, //!< RFC1928: Command not supported
ATYPEUNSUPPORTED = 0x08, //!< Address type not supported ATYPEUNSUPPORTED = 0x08, //!< RFC1928: Address type not supported
TOR_HS_DESC_NOT_FOUND = 0xf0, //!< Tor: Onion service descriptor can not be found
TOR_HS_DESC_INVALID = 0xf1, //!< Tor: Onion service descriptor is invalid
TOR_HS_INTRO_FAILED = 0xf2, //!< Tor: Onion service introduction failed
TOR_HS_REND_FAILED = 0xf3, //!< Tor: Onion service rendezvous failed
TOR_HS_MISSING_CLIENT_AUTH = 0xf4, //!< Tor: Onion service missing client authorization
TOR_HS_WRONG_CLIENT_AUTH = 0xf5, //!< Tor: Onion service wrong client authorization
TOR_HS_BAD_ADDRESS = 0xf6, //!< Tor: Onion service invalid address
TOR_HS_INTRO_TIMEOUT = 0xf7, //!< Tor: Onion service introduction timed out
}; };
/** Values defined for ATYPE in RFC1928 */ /** Values defined for ATYPE in RFC1928 */
@ -364,8 +372,24 @@ static std::string Socks5ErrorString(uint8_t err)
return "protocol error"; return "protocol error";
case SOCKS5Reply::ATYPEUNSUPPORTED: case SOCKS5Reply::ATYPEUNSUPPORTED:
return "address type not supported"; return "address type not supported";
case SOCKS5Reply::TOR_HS_DESC_NOT_FOUND:
return "onion service descriptor can not be found";
case SOCKS5Reply::TOR_HS_DESC_INVALID:
return "onion service descriptor is invalid";
case SOCKS5Reply::TOR_HS_INTRO_FAILED:
return "onion service introduction failed";
case SOCKS5Reply::TOR_HS_REND_FAILED:
return "onion service rendezvous failed";
case SOCKS5Reply::TOR_HS_MISSING_CLIENT_AUTH:
return "onion service missing client authorization";
case SOCKS5Reply::TOR_HS_WRONG_CLIENT_AUTH:
return "onion service wrong client authorization";
case SOCKS5Reply::TOR_HS_BAD_ADDRESS:
return "onion service invalid address";
case SOCKS5Reply::TOR_HS_INTRO_TIMEOUT:
return "onion service introduction timed out";
default: default:
return "unknown"; return strprintf("unknown (0x%02x)", err);
} }
} }