### Basic Usage Example Source: https://docs.21.dev/data/documentation/tor/torclient A practical example demonstrating the basic usage of TorClient. ```APIDOC ```swift let client = TorClient(configuration: .ephemeral()) try await client.start() try await client.waitUntilBootstrapped() print("SOCKS reachable at \(await client.socksEndpoint!)") let control = try await client.control() let service = try await control.addOnion( key: .newV3(discardPrivateKey: true), ports: [.toLocalPort(80, localPort: 8080)] ) await client.stop() ``` ``` -------------------------------- ### Start and Stop Tor Client Source: https://docs.21.dev/data/documentation/tor Demonstrates the basic lifecycle of a TorClient: initialization, starting, waiting for bootstrap, inspecting the SOCKS5 endpoint, and stopping the client. Ensure the client is properly started and stopped to manage the Tor instance. ```swift import Tor let client = TorClient(configuration: .ephemeral()) try await client.start() try await client.waitUntilBootstrapped() print("SOCKS5 reachable at \(await client.socksEndpoint!)") await client.stop() ``` -------------------------------- ### start() Source: https://docs.21.dev/data/documentation/tor/torsession Starts the underlying Tor instance. This method is part of the TorSession protocol for managing the Tor lifecycle. ```APIDOC ## start() ### Description Start the underlying Tor instance. ### Method async ### Endpoint N/A (Protocol method) ``` -------------------------------- ### Start Tor Client and Wait for Bootstrap Source: https://docs.21.dev/data/documentation/tor/gettingstarted Initialize a TorClient actor with a TorConfiguration and start the embedded Tor process. Block until Tor reports 100% bootstrap progress using waitUntilBootstrapped. -------------------------------- ### Start Tor Instance Source: https://docs.21.dev/data/documentation/tor/torsession Starts the underlying Tor instance. This method is part of the TorSession protocol for managing the Tor lifecycle. ```swift func start() ``` -------------------------------- ### TorClient Start and Stop Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Methods to start and stop the Tor client service. ```APIDOC ## TorClient Start and Stop ### Description Controls the lifecycle of the Tor client service. Use `start()` to initiate the connection and `stop()` to terminate it. ### Methods - `start()`: Starts the Tor client service. - `stop()`: Stops the Tor client service. ### Example ```swift let torClient = TorClient.init() torClient.start() // ... perform operations ... torClient.stop() ``` ``` -------------------------------- ### Basic TorClient Usage Source: https://docs.21.dev/data/documentation/tor/torclient Demonstrates the basic lifecycle and functionality of TorClient, including starting, bootstrapping, accessing SOCKS endpoint, creating an onion service, and stopping the client. ```swift let client = TorClient(configuration: .ephemeral()) try await client.start() try await client.waitUntilBootstrapped() print("SOCKS reachable at \(await client.socksEndpoint!)") let control = try await client.control() let service = try await control.addOnion( key: .newV3(discardPrivateKey: true), ports: [.toLocalPort(80, localPort: 8080)] ) await client.stop() ``` -------------------------------- ### TorClient Lifecycle Management Source: https://docs.21.dev/data/documentation/tor/torclient Methods to start, stop, and monitor the lifecycle of the Tor instance. ```APIDOC ## Lifecycle ### `start()` Start the embedded Tor process. ### `stop()` Stop the Tor instance and release all associated resources. ### `waitUntilBootstrapped(timeout:)` Block until Tor reports 100% bootstrap, or fail after `timeout`. ``` -------------------------------- ### Get Fully-Qualified Onion Address Source: https://docs.21.dev/data/documentation/tor/onionservice Constructs the fully-qualified '.onion' address by appending '.onion' to the service identifier. ```swift var onionAddress: String { get } ``` -------------------------------- ### TorControlClient Get Bootstrap Status Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Retrieves the current bootstrap status of the Tor client. ```APIDOC ## TorControlClient Get Bootstrap Status ### Description Retrieves the current status of the Tor client's bootstrapping process. This indicates how far Tor has progressed in connecting to the network. ### Method - `getBootstrapStatus()`: Returns the bootstrap status. ### Response - Returns a `BootstrapStatus` object or similar structure detailing the progress. ### Example ```swift let torClient = TorClient.init() let controlClient = torClient.control() try { let status = try controlClient.getBootstrapStatus() print("Bootstrap status: \(status)") } catch { print("Failed to get bootstrap status: \(error)") } ``` ``` -------------------------------- ### TorSession Source: https://docs.21.dev/data/documentation/tor/llms.txt Public Sendable protocol that TorClient conforms to. It offers a minimal interface for starting, stopping, waiting, and observing the Tor instance, suitable for dependency injection and testing. ```APIDOC ## TorSession ### Description Public `Sendable` protocol that `TorClient` conforms to. Provides a minimal start/stop/wait/observe seam for dependency injection. ### Usage Accept `any TorSession` in function signatures when you want testable code or to substitute a non-production conformer. ``` -------------------------------- ### Get Onion Service Creation Timestamp Source: https://docs.21.dev/data/documentation/tor/onionservice Retrieves the wall-clock time at which the OnionService value was constructed. ```swift let createdAt: Date ``` -------------------------------- ### Get Tor Bootstrap Status Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Fetches and parses Tor's current bootstrap status. This is useful for monitoring the progress of Tor's network initialization. ```swift func getBootstrapStatus() async throws -> TorBootstrapStatus ``` -------------------------------- ### Get Tor SOCKS Endpoint Source: https://docs.21.dev/data/documentation/tor/torsession An asynchronous getter for Tor's local SOCKS5 proxy endpoint. The endpoint is nil until the port is known. ```swift var socksEndpoint: NWEndpoint? { get async } ``` -------------------------------- ### Get Onion Service Private Key Source: https://docs.21.dev/data/documentation/tor/onionservice Accesses the base64-encoded ED25519-V3 private key. This property is nil if the private key was discarded during creation. ```swift let privateKey: Data? ``` -------------------------------- ### TorClient Source: https://docs.21.dev/data/documentation/tor/llms.txt Actor-isolated driver for a single embedded Tor instance. It provides methods to start, stop, and manage the Tor instance's lifecycle, along with access to its SOCKS endpoint, events, and control interface. ```APIDOC ## TorClient ### Description Actor-isolated driver for a single embedded Tor instance. Provides methods to start, stop, and manage the Tor instance's lifecycle. ### Methods - `start()`: Starts the Tor instance. - `stop()`: Stops the Tor instance. - `waitUntilBootstrapped(timeout:)`: Waits until the Tor instance is bootstrapped, with an optional timeout. - `socksEndpoint`: Property to access the SOCKS endpoint of the Tor instance. - `events`: Property to access the events stream of the Tor instance. - `control()`: Returns a `TorControlClient` for interacting with the Tor control protocol. - `makeURLSession(ephemeral:)` (Apple-only): Creates a URLSession configured to use the Tor instance. ``` -------------------------------- ### TorClient Initialization Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Demonstrates how to initialize the Tor client with default settings or a custom configuration. ```APIDOC ## TorClient Initialization ### Description Initializes the Tor client. You can use the default configuration or provide a custom `TorConfiguration` object. ### Methods - `init()`: Initializes the Tor client with default settings. - `init(configuration: TorConfiguration)`: Initializes the Tor client with a specific configuration. ### Example ```swift // Using default configuration let torClient = TorClient.init() // Using custom configuration let config = TorConfiguration.init(dataDirectory: "/path/to/data", socksPort: 9050) let customTorClient = TorClient.init(configuration: config) ``` ``` -------------------------------- ### Initialize TorControlClient with File Descriptor Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Wraps a raw file descriptor to create a TorControlClient. Optionally marks the connection as pre-authenticated. Useful for integrating with existing processes or specific system configurations. ```swift init(fileDescriptor: Int32, preAuthenticated: Bool, dataDirectory: URL? = nil) ``` -------------------------------- ### Make Default TorConfiguration Source: https://docs.21.dev/data/documentation/tor/torconfiguration Returns a TorConfiguration rooted at a fresh temporary directory. Use this to create a baseline configuration. ```swift TorConfiguration.makeDefault() ``` -------------------------------- ### TorClient Initialization Source: https://docs.21.dev/data/documentation/tor/torclient Initializes a TorClient with a specific configuration or a default one. ```APIDOC ## Initializers ### `init(configuration:)` Create a client bound to a specific `TorConfiguration`. ### `init()` Convenience initialiser using `TorConfiguration.makeDefault()`. ``` -------------------------------- ### Get Onion Service ID Source: https://docs.21.dev/data/documentation/tor/onionservice Retrieves the 56-character v3 service identifier for the onion service, excluding the '.onion' suffix. ```swift let serviceID: String ``` -------------------------------- ### TorConfiguration Initialization Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Initializes the Tor configuration with various options. ```APIDOC ## TorConfiguration Initialization ### Description Initializes `TorConfiguration` with detailed settings for the Tor client. ### Method - `init(dataDirectory: String?, cacheDirectory: String?, socksPort: Int, cookieAuthentication: Bool, controlPassword: String?, extraArgs: [String]?, ownsDataDirectory: Bool)`: Creates a configuration object. ### Parameters - `dataDirectory` (String?): Path to the data directory. - `cacheDirectory` (String?): Path to the cache directory. - `socksPort` (Int): The SOCKS port to use. - `cookieAuthentication` (Bool): Whether to use cookie authentication. - `controlPassword` (String?): The control port password, if authentication is required. - `extraArgs` ([String]?): Additional arguments to pass to Tor. - `ownsDataDirectory` (Bool): Indicates if the configuration owns the data directory. ### Example ```swift let config = TorConfiguration.init( dataDirectory: "/var/lib/tor", cacheDirectory: "/var/cache/tor", socksPort: 9050, cookieAuthentication: false, controlPassword: nil, extraArgs: ["--log", "info notice file /var/log/tor/log"] ownsDataDirectory: false ) ``` ``` -------------------------------- ### Async TCP Server with Event Source: https://docs.21.dev/data/documentation/event/llms.txt Implement an asynchronous TCP server using the Event package. Bind to a port and iterate over incoming connections, handling each in a separate Task. ```swift import Event let server = try await Socket.listen(port: 8080, backlog: 16, loop: .shared) for try await client in server.connections { Task { do { while true { let chunk = try await client.read(timeout: .seconds(30)) try await client.write(chunk, timeout: .seconds(30)) } } catch SocketError.connectionClosed { // Peer closed cleanly. } try? await client.close() } } ``` -------------------------------- ### waitUntilBootstrapped() Source: https://docs.21.dev/data/documentation/tor/torsession Waits up to the default 120-second bootstrap window for Tor to become fully bootstrapped. A convenience method for common scenarios. ```APIDOC ## waitUntilBootstrapped() ### Description Wait up to the default 120-second bootstrap window. ### Method async throws ### Endpoint N/A (Protocol method) ``` -------------------------------- ### Initialize TorConfiguration Source: https://docs.21.dev/data/documentation/tor/torconfiguration Memberwise initializer for TorConfiguration with sensible defaults for all fields. Allows customization of paths, ports, authentication, and extra arguments. ```swift TorConfiguration(dataDirectory: URL(fileURLWithPath: "/path/to/data"), cacheDirectory: nil, socksPort: nil, cookieAuthentication: false, controlPassword: nil, extraArgs: ["--log", "info console.log"], ownsDataDirectory: true) ``` -------------------------------- ### Initialize TorControlClient with Host and Port Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Opens a TCP connection to a specified Tor control port and wraps it in a TorControlClient. Use this to connect to a Tor instance listening on a network address. ```swift init(host: String, port: Int, dataDirectory: URL? = nil) ``` -------------------------------- ### Initialize TorControlClient with ControlSocket Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Wraps an existing ControlSocket to create a TorControlClient instance. Use this when you already have an established control socket connection. ```swift init(socket: ControlSocket, dataDirectory: URL? = nil) ``` -------------------------------- ### waitUntilBootstrapped(timeout:) Source: https://docs.21.dev/data/documentation/tor/torsession Blocks until Tor reports 100% bootstrap progress or fails after the specified timeout. Essential for ensuring Tor is ready before proceeding. ```APIDOC ## waitUntilBootstrapped(timeout:) ### Description Block until Tor reports 100% bootstrap progress, or fail after `timeout`. ### Method async throws ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters - **timeout** (TimeInterval) - Required - The maximum time to wait for bootstrapping. ### Response #### Success Response (Void) Indicates that Tor has successfully bootstrapped within the given timeout. ### Endpoint N/A (Protocol method) ``` -------------------------------- ### TorControlClient.init Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Initializes the Tor control client connection. Multiple initialization methods are available based on the connection type. ```APIDOC ## Initialization Methods ### Description Initializes the Tor control client. Choose the method that best suits your connection requirements. ### Methods #### 1. `init(filedescriptor: preauthenticated: dataDirectory:)` - **Parameters**: - `filedescriptor` (Int) - The file descriptor for the control socket. - `preauthenticated` (Bool) - Whether the connection is pre-authenticated. - `dataDirectory` (String) - The path to the Tor data directory. #### 2. `init(host: port: dataDirectory:)` - **Parameters**: - `host` (String) - The hostname or IP address of the Tor control port. - `port` (Int) - The port number of the Tor control port. - `dataDirectory` (String) - The path to the Tor data directory. #### 3. `init(socket: dataDirectory:)` - **Parameters**: - `socket` (Socket) - The socket object for the control connection. - `dataDirectory` (String) - The path to the Tor data directory. ``` -------------------------------- ### Pin swift-tor Dependency with Exact Version Source: https://docs.21.dev/data/documentation/tor/productionconsiderations To avoid unexpected migrations before the first 1.0 release, pin a specific version of swift-tor using `exact:` in your Package.swift file. ```swift .package(url: "https://github.com/21-DOT-DEV/swift-tor.git", exact: "0.1.0") ``` -------------------------------- ### Configuration and Events Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Allows setting Tor's runtime configuration and subscribing to asynchronous events. ```APIDOC ### Configuration & events ### `setConf(_:)` Issue a `SETCONF` command to mutate Tor’s runtime configuration. ### `subscribe(to:)` Subscribe to Tor async events and return a stream of decoded messages. ``` -------------------------------- ### TorControlClient Initialization Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Initializes a TorControlClient by wrapping an existing ControlSocket, a raw file descriptor, or by opening a new TCP connection to the Tor control port. ```APIDOC ## Initializers ### `init(socket:dataDirectory:)` Wrap an existing [`ControlSocket`](/documentation/Tor/ControlSocket). ### `init(fileDescriptor:preAuthenticated:dataDirectory:)` Wrap a raw file descriptor, optionally marking it as pre-authenticated. ### `init(host:port:dataDirectory:)` Open a TCP connection to a listening Tor control port and wrap it. ``` -------------------------------- ### Wait Until Tor Bootstrapped (Default Timeout) Source: https://docs.21.dev/data/documentation/tor/torsession Waits up to the default 120-second bootstrap window for Tor to become fully bootstrapped. This is a convenience method for the waitUntilBootstrapped(timeout:) function. ```swift func waitUntilBootstrapped() ``` -------------------------------- ### Async TCP Client with Timeouts Source: https://docs.21.dev/data/documentation/event/llms.txt Establish an asynchronous TCP client connection using the Event package. Supports per-operation timeouts, throwing `SocketError.timeout` on expiry. ```swift import Event let socket = try await Socket.connect( to: "127.0.0.1", port: 8080, loop: .shared, timeout: .seconds(5) ) try await socket.write(Data("ping\n".utf8), timeout: .seconds(5)) let reply = try await socket.read(maxBytes: 4096, timeout: .seconds(5)) try await socket.close() ``` -------------------------------- ### TorConfiguration Make Default Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Sets the current configuration as the default for subsequent Tor client instances. ```APIDOC ## TorConfiguration Make Default ### Description Sets the current `TorConfiguration` instance as the default configuration to be used by any `TorClient` instances initialized without explicit configuration. ### Method - `makeDefault()`: Makes the current configuration the default. ### Example ```swift let config = TorConfiguration.init(socksPort: 9050) config.makeDefault() // Any subsequent TorClient() will use this configuration let torClient = TorClient.init() ``` ``` -------------------------------- ### TorClient Wait Until Bootstrapped Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Waits for the Tor client to complete its bootstrapping process. ```APIDOC ## TorClient Wait Until Bootstrapped ### Description Waits until the Tor client has successfully bootstrapped and is ready for use. An optional timeout can be specified. ### Methods - `waitUntilBootstrapped()`: Waits indefinitely until bootstrapping is complete. - `waitUntilBootstrapped(timeout: TimeInterval)`: Waits for a specified duration for bootstrapping to complete. ### Example ```swift let torClient = TorClient.init() torClient.start() // Wait indefinitely torClient.waitUntilBootstrapped() // Wait with a timeout of 60 seconds torClient.waitUntilBootstrapped(timeout: 60.0) ``` ``` -------------------------------- ### Add Swift Event Package Dependency Source: https://docs.21.dev/data/documentation/event/llms.txt Add the Event package dependency to your Swift project's Package.swift file. Use `exact:` for pre-1.0 versions. ```swift // Package.swift .package(url: "https://github.com/21-DOT-DEV/swift-event.git", exact: "0.2.1"), .target(name: "", dependencies: [ .product(name: "Event", package: "swift-event"), ]), ``` -------------------------------- ### Wait Until Tor Bootstrapped with Timeout Source: https://docs.21.dev/data/documentation/tor/torsession Blocks until Tor reports 100% bootstrap progress or fails after the specified timeout. This method is crucial for ensuring Tor is ready before proceeding. ```swift func waitUntilBootstrapped(timeout: TimeInterval) ``` -------------------------------- ### Initialize OnionService Source: https://docs.21.dev/data/documentation/tor/onionservice Memberwise initializer for creating an OnionService instance, typically used for test fixtures or replaying persisted state. ```swift init(serviceID: privateKey: createdAt:) ``` -------------------------------- ### TorControlClient.setConf Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Sets Tor configuration options. ```APIDOC ## POST /setConf ### Description Sets one or more Tor configuration options. ### Method POST ### Endpoint /setConf ### Parameters #### Request Body - **options** (object) - Required - A dictionary of configuration options to set. Keys are option names, and values are their desired settings. - **(optionName)** (string) - The name of the configuration option. - **(optionValue)** (string) - The value to set for the configuration option. ### Response #### Success Response (200) - **(message)** (string) - Confirmation message indicating the configuration has been updated. ``` -------------------------------- ### GETINFO Commands Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Provides methods to fetch information from Tor using the GETINFO command. ```APIDOC ## GETINFO ### `getInfo(_:)` Issue a multi-key `GETINFO` command (control-spec.txt §3.9). ### `getInfo(_:)` Convenience: issue `GETINFO` for a single key. ### `getBootstrapStatus()` Fetch and parse Tor’s current bootstrap status. ``` -------------------------------- ### newIdentity() Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Ask Tor to rotate circuits by sending the NEWNYM signal. ```APIDOC ## newIdentity() ### Description Ask Tor to rotate circuits (`SIGNAL NEWNYM`). ### Method APIDOC ### Endpoint APIDOC ``` -------------------------------- ### TorConfiguration Struct Source: https://docs.21.dev/data/documentation/tor/torconfiguration Represents the configuration for a TorClient. It is Sendable and mutable. ```swift struct TorConfiguration ``` -------------------------------- ### Observe Tor Lifecycle Events Source: https://docs.21.dev/data/documentation/tor/torsession Provides a back-pressure-aware asynchronous stream of TorEvent values for the session. This allows monitoring the lifecycle and state changes of the Tor instance. ```swift var events: AsyncStream { get } ``` -------------------------------- ### shutdown() Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Ask Tor to exit cleanly by sending the SHUTDOWN signal. ```APIDOC ## shutdown() ### Description Ask Tor to exit cleanly (`SIGNAL SHUTDOWN`). ### Method APIDOC ### Endpoint APIDOC ``` -------------------------------- ### Generate New Onion Service Private Key Source: https://docs.21.dev/data/documentation/tor/productionconsiderations Use `OnionKeySpec.newV3(discardPrivateKey:)` with `true` when re-adoption of an onion service is not necessary. This minimizes the attack surface by discarding the private key after it's used, especially for single-session services. ```swift OnionKeySpec.newV3(discardPrivateKey: true) ``` -------------------------------- ### Set Tor Configuration Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Issues a SETCONF command to modify Tor's runtime configuration. This allows dynamic adjustment of Tor's behavior. ```swift func setConf(_ conf: [String : String]) async throws ``` -------------------------------- ### Issue Multi-Key GETINFO Command Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Issues a GETINFO command with multiple keys to retrieve various status information from Tor. The keys are provided as an array of strings. ```swift func getInfo(_ keys: [String]) async throws -> [String : String] ``` -------------------------------- ### Check Authentication Status Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Returns true if the client has been successfully authenticated or was constructed as pre-authenticated. This property indicates readiness for sending authenticated commands. ```swift var isAuthenticated: Bool ``` -------------------------------- ### Add Onion Service (Ephemeral, Tied to Connection) Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Registers an ephemeral v3 onion service using the ADD_ONION command. The service is tied to the control connection and will be removed when the socket closes. ```swift func addOnion(key: OnionKey, ports: [OnionServicePort], detach: Bool = false) async throws -> OnionServiceID ``` -------------------------------- ### Loop-Scheduled Timers with EventLoop Source: https://docs.21.dev/data/documentation/event/llms.txt Utilize the EventLoop for scheduling timers. `sleep(for:)` provides asynchronous waiting, while `schedule(after:_:)` offers a fire-and-forget callback mechanism. ```swift import Event // Async sleep, driven by the loop: await EventLoop.shared.sleep(for: .milliseconds(250)) // Fire-and-forget callback: EventLoop.shared.schedule(after: .seconds(1)) { print("one second later") } ``` -------------------------------- ### TorControlClient Add Onion Service Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Adds a new onion service. ```APIDOC ## TorControlClient Add Onion Service ### Description Adds a new hidden service (onion service) to Tor. You can specify the key type, ports to expose, and whether to detach the service. ### Method - `addOnion(key: String, ports: [String], detach: Bool)`: Adds a new onion service. ### Parameters - `key` (String): The private key for the onion service. - `ports` ([String]): An array of strings defining the virtual port mappings (e.g., `"80 VirtualPort"`). - `detach` (Bool): If true, the service will run in the background. ### Example ```swift let torClient = TorClient.init() let controlClient = torClient.control() try { let onionAddress = try controlClient.addOnion(key: "auto", ports: ["80 VirtualPort 127.0.0.1:8080"], detach: true) print("Onion service created: \(onionAddress)") } catch { print("Failed to add onion service: \(error)") } ``` ``` -------------------------------- ### Issue Single-Key GETINFO Command Source: https://docs.21.dev/data/documentation/tor/torcontrolclient A convenience method to issue a GETINFO command for a single key. This simplifies retrieving specific pieces of information from Tor. ```swift func getInfo(_ key: String) async throws -> String ``` -------------------------------- ### OpenSSL Runtime Metadata Source: https://docs.21.dev/data/documentation/openssl/llms.txt Access runtime metadata about the statically linked OpenSSL version for auditing purposes. ```APIDOC ## OpenSSL Runtime Metadata ### Description Access runtime metadata about the statically linked OpenSSL version for auditing purposes. ### Property - `SSL.versionString`: A string representing the version of the statically linked OpenSSL library. ``` -------------------------------- ### Ephemeral TorConfiguration Source: https://docs.21.dev/data/documentation/tor/torconfiguration Returns a self-cleaning ephemeral TorConfiguration. Optionally keeps a warm cache directory. ```swift TorConfiguration.ephemeral(cacheDirectory: "/path/to/cache") ``` -------------------------------- ### ServerSocket API Source: https://docs.21.dev/data/documentation/event/llms.txt Enables the creation and management of TCP server sockets to accept incoming connections. ```APIDOC ## ServerSocket ### Description Enables the creation and management of TCP server sockets to accept incoming connections. ### Methods - `accept()`: Accepts an incoming connection. - `close()`: Closes the server socket. ### Properties - `.connections`: An `AsyncThrowingStream` that yields inbound `Socket` instances. ``` -------------------------------- ### socksEndpoint Source: https://docs.21.dev/data/documentation/tor/torsession Provides access to Tor's local SOCKS5 proxy endpoint. This property is nil until the port is known, indicating Tor is ready to accept connections. ```APIDOC ## socksEndpoint ### Description Tor’s local SOCKS5 proxy endpoint, `nil` until the port is known. ### Method async getter ### Endpoint N/A (Protocol property) ``` -------------------------------- ### OnionService Source: https://docs.21.dev/data/documentation/tor/llms.txt Represents a successfully created v3 hidden service. It includes the onion address and optionally the private key for re-adoption, along with port mappings. ```APIDOC ## OnionService ### Description A successfully-created v3 hidden service. ### Properties - `onionAddress`: The `.onion` URL of the hidden service. - `privateKey`: Optional private key for re-adoption of the service. - `portMappings`: Mappings between the service's ports. ``` -------------------------------- ### TorControlClient.sendRaw Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Sends a raw command to the Tor control port. ```APIDOC ## POST /sendRaw ### Description Sends a raw command string directly to the Tor control port. ### Method POST ### Endpoint /sendRaw ### Parameters #### Request Body - **command** (string) - Required - The raw command to send to the Tor control port. ### Response #### Success Response (200) - **(response)** (string) - The raw response from the Tor control port. ``` -------------------------------- ### Add Onion Service (Ephemeral, Detached) Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Registers an ephemeral v3 onion service using the ADD_ONION command. The service will persist even after the control connection closes, until explicitly deleted or Tor exits. ```swift func addOnion(key: OnionKey, ports: [OnionServicePort], detach: Bool = true) async throws -> OnionServiceID ``` -------------------------------- ### events Source: https://docs.21.dev/data/documentation/tor/torsession An asynchronous stream of TorEvent values for the session, designed with back-pressure awareness. Useful for observing Tor's lifecycle events. ```APIDOC ## events ### Description Back-pressure-aware async stream of [`TorEvent`](/documentation/Tor/TorEvent) values for this session. ### Method async getter ### Endpoint N/A (Protocol property) ``` -------------------------------- ### Signal-Driven Shutdown with EventLoop Source: https://docs.21.dev/data/documentation/event/llms.txt Handle signals like SIGINT and SIGTERM for graceful shutdown using the Event package's `signalStream`. The stream yields each time a requested signal fires. ```swift import Event #if canImport(Darwin) import Darwin #else import Glibc #endif let loop = EventLoop.shared Task { for await sig in loop.signalStream(SIGINT, SIGTERM) { print("received signal \(sig) — shutting down") break } } ``` -------------------------------- ### signal(_:) Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Send a SIGNAL command to Tor. This is a general-purpose method for sending various signals as defined in control-spec.txt §3.7. ```APIDOC ## signal(_:) ### Description Send a `SIGNAL` command to Tor (control-spec.txt §3.7). ### Method APIDOC ### Endpoint APIDOC ### Parameters #### Path Parameters - **signalType** (string) - Required - The type of signal to send (e.g., NEWNYM, SHUTDOWN). ``` -------------------------------- ### TorConfiguration Source: https://docs.21.dev/data/documentation/tor/llms.txt Value-type configuration for the TorClient. Allows customization of the data directory, cache directory, SOCKS port policy, log level, and control-port options. ```APIDOC ## TorConfiguration ### Description Value-type configuration passed to `TorClient` at construction. Allows customization of various Tor settings. ### Properties - `dataDirectory`: The directory for Tor's data. - `cacheDirectory`: Optional directory for caching to enable fast warm-boot. - `socksPortPolicy`: Policy for SOCKS port assignment. - `logLevel`: The logging level for Tor. - `controlPortOptions`: Options for the control port. ### Common Cases - Use `.makeDefault()` for common configurations. - Use `.ephemeral(cacheDirectory:)` for temporary, cache-enabled configurations. ``` -------------------------------- ### Define OnionService Structure Source: https://docs.21.dev/data/documentation/tor/onionservice Defines the OnionService structure which holds information about a Tor onion service. ```swift struct OnionService ``` -------------------------------- ### TorControlClient Authenticate Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Authenticates with the Tor control port. ```APIDOC ## TorControlClient Authenticate ### Description Authenticates the control client connection using the provided password. ### Method - `authenticate(password: String)`: Authenticates with the given password. ### Parameters - `password` (String): The password for control port authentication. ### Example ```swift let torClient = TorClient.init() let controlClient = torClient.control() try { try controlClient.authenticate(password: "your_control_password") print("Authentication successful") } catch { print("Authentication failed: \(error)") } ``` ``` -------------------------------- ### TorControlClient Class Definition Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Defines the TorControlClient class, a Sendable high-level client for Tor's control protocol. ```swift final class TorControlClient ``` -------------------------------- ### TorClient Observation Source: https://docs.21.dev/data/documentation/tor/torclient Accessors for observing the current state and events of the Tor instance. ```APIDOC ## Observing ### `state` Current lifecycle state, isolated to the actor. ### `socksEndpoint` Tor’s local SOCKS5 proxy endpoint once start succeeds, else `nil`. ### `events` Fresh fan-out `AsyncStream` of `TorEvent` values. ``` -------------------------------- ### EventLoop API Source: https://docs.21.dev/data/documentation/event/llms.txt The core event loop for managing asynchronous operations. It supports platform-optimal backends like kqueue and epoll. ```APIDOC ## EventLoop ### Description The core event loop for managing asynchronous operations. It selects `kqueue` on Apple or `epoll` on Linux. ### Methods - `backendMethod`: For runtime verification of the backend. - `.shared`: Access the shared instance of the EventLoop. - `init()`: Initializes a new EventLoop. - `run()`: Starts the event loop. - `runOnce()`: Runs the event loop for a single iteration. - `stop()`: Stops the event loop. - `sleep(for:)`: Pauses the event loop for a specified duration. - `schedule(after:_:)`: Schedules a closure to be executed after a delay. - `signalStream(_:)`: Sets up a stream for receiving signals. ``` -------------------------------- ### Onion Service Management Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Manages the lifecycle of onion services, including registration and deletion. ```APIDOC ### Onion services ### `addOnion(key:ports:detach:)` Register an ephemeral v3 onion service via `ADD_ONION` (control-spec.txt §3.27). ### `delOnion(_:)` Remove an ephemeral onion service by its service ID (`DEL_ONION`, control-spec.txt §3.28). ### `delOnion(_:)` Convenience overload: delete an onion service by value. ``` -------------------------------- ### TorControlClient.signal Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Sends a signal to the Tor process. ```APIDOC ## POST /signal ### Description Sends a signal to the Tor process to perform a specific action. ### Method POST ### Endpoint /signal ### Parameters #### Request Body - **signal** (string) - Required - The name of the signal to send (e.g., 'RELOAD', 'NEWNYM'). ### Response #### Success Response (200) - **(message)** (string) - Confirmation message indicating the signal has been sent. ``` -------------------------------- ### TorControlClient.getInfo Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Retrieves information from the Tor control port. This method can be called in multiple ways, as indicated by the different signatures. ```APIDOC ## GET /getinfo ### Description Retrieves various information from the Tor control port. ### Method GET ### Endpoint /getinfo ### Parameters #### Query Parameters - **(arguments)** (string) - Required - A comma-separated list of information keys to retrieve. ### Response #### Success Response (200) - **(response)** (string) - The requested information from the Tor control port. ``` -------------------------------- ### RSA PEM Ingestion Source: https://docs.21.dev/data/documentation/openssl/llms.txt Namespace for RSA key operations, specifically for ingesting RSA private and public keys in PEM format. ```APIDOC ## RSA PEM Ingestion ### Description Namespace for RSA key operations, specifically for ingesting RSA private and public keys in PEM format. ### Types - `RSA.PrivateKey`: Represents an RSA private key. Initialized via `init(pemRepresentation:)` and exposes its PEM data via `.pemData`. - `RSA.PublicKey`: Represents an RSA public key. Initialized via `init(pemRepresentation:)` and exposes its PEM data via `.pemData`. ``` -------------------------------- ### Authentication Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Handles the authentication handshake with the Tor control port and checks the authentication status. ```APIDOC ## Authentication ### `authenticate(password:)` Perform the `AUTHENTICATE` handshake (control-spec.txt §3.5). ### `isAuthenticated` `true` once any successful `AUTHENTICATE` (or pre-auth construction) has marked this client ready. ``` -------------------------------- ### Socket API Source: https://docs.21.dev/data/documentation/event/llms.txt Provides asynchronous TCP socket functionality for connecting, reading, and writing data. ```APIDOC ## Socket ### Description Provides asynchronous TCP socket functionality for connecting, reading, and writing data. ### Methods - `connect(to:loop:timeout:)`: Connects to a given host and port with a timeout. - `connect(to:port:loop:timeout:)`: Connects to a given host and port with a timeout. - `listen(port:backlog:loop:)`: Starts listening for incoming connections on a specified port. - `read(maxBytes:timeout:)`: Reads data from the socket with a maximum byte limit and timeout. - `write(_:timeout:)`: Writes data to the socket with a timeout. - `close()`: Closes the socket connection. ``` -------------------------------- ### SocketAddress API Source: https://docs.21.dev/data/documentation/event/llms.txt Represents network addresses, supporting both IPv4 and IPv6 configurations. ```APIDOC ## SocketAddress ### Description Represents network addresses, supporting both IPv4 and IPv6 configurations. ### Constructors - `ipv4(_:port:)`: Creates an IPv4 address. - `ipv6(_:port:)`: Creates an IPv6 address. - `anyIPv4(port:)`: Creates a wildcard IPv4 address. - `from(storage:length:)`: Creates a SocketAddress from raw `sockaddr_storage`. ### Accessors - `port`: Retrieves the port number of the address. ``` -------------------------------- ### Subscribe to Tor Events Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Subscribes to Tor's asynchronous events and returns a stream of decoded messages. This enables real-time monitoring of Tor's state changes. ```swift func subscribe(to events: Set) -> AsyncThrowingStream ``` -------------------------------- ### OpenSSLError Handling Source: https://docs.21.dev/data/documentation/openssl/llms.txt Provides typed errors for OpenSSL operations, conforming to the `LocalizedError` protocol. ```APIDOC ## OpenSSLError Handling ### Description Provides typed errors for OpenSSL operations, conforming to the `LocalizedError` protocol. ### Error Types - `invalidInput` - `invalidKey` - `invalidSignature` - `signingFailed` - `verificationFailed` - `underlyingError` ``` -------------------------------- ### Add swift-tor Package Dependency Source: https://docs.21.dev/data/documentation/tor/gettingstarted Add swift-tor as a package dependency using Swift Package Manager. Track the 'main' branch for the latest audited code until a tagged release is available. ```swift .package(url: "https://github.com/21-DOT-DEV/swift-tor.git", branch: "main") ``` -------------------------------- ### Authenticate TorControlClient Source: https://docs.21.dev/data/documentation/tor/torcontrolclient Performs the AUTHENTICATE handshake with the Tor control port. This is a required step after establishing a connection unless the client is constructed as pre-authenticated. ```swift func authenticate(password: String) async throws ``` -------------------------------- ### stop() Source: https://docs.21.dev/data/documentation/tor/torsession Stops the Tor instance and releases any associated resources. This is a key operation within the TorSession protocol. ```APIDOC ## stop() ### Description Stop the Tor instance and release any resources. ### Method async ### Endpoint N/A (Protocol method) ``` -------------------------------- ### TorControlClient.subscribe Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Subscribes to specific Tor control events. ```APIDOC ## POST /subscribe ### Description Subscribes to receive notifications for specified Tor control events. ### Method POST ### Endpoint /subscribe ### Parameters #### Request Body - **events** (array) - Required - A list of event names to subscribe to (e.g., ['CIRC', 'STREAM']). ### Response #### Success Response (200) - **(message)** (string) - Confirmation message indicating subscription to the specified events. ``` -------------------------------- ### TorClient Control Access Source: https://docs.21.dev/data/documentation/tor/torclient Methods to access the control client and configuration. ```APIDOC ## Control access ### `control()` Return the `TorControlClient` bound to this Tor instance. ### `configuration` The immutable `TorConfiguration` snapshot used to start Tor. ``` -------------------------------- ### TorControlClient.shutdown Source: https://docs.21.dev/data/documentation/tor/llms-full.txt Shuts down the Tor process gracefully. ```APIDOC ## POST /shutdown ### Description Initiates a graceful shutdown of the Tor process. ### Method POST ### Endpoint /shutdown ### Response #### Success Response (200) - **(message)** (string) - Confirmation message indicating that Tor is shutting down. ``` -------------------------------- ### TorError Enumeration Cases Source: https://docs.21.dev/data/documentation/tor/torerror This section details the various cases within the TorError enumeration, categorized by the type of failure they represent. Each case describes a specific error condition and its potential associated values. ```APIDOC ## TorError Canonical error surface for every swift-tor failure mode. ```swift enum TorError ``` ### Overview `TorError` consolidates every expected failure across the embedded Tor process lifecycle, the control protocol, onion-service management, and low-level I/O into a single `Sendable`/`Hashable` enum. Callers can `switch` exhaustively in one place instead of catching heterogeneous `Error` conformers from `Foundation`, `POSIX`, and the control layer. Associated-value payloads are `String` (or a `(code: Int, message: String)` tuple) so the concrete details of each failure are carried through without requiring downstream code to know the underlying machinery. Cases are grouped by concern: **Lifecycle** covers [`TorError.alreadyStarted`](/documentation/Tor/TorError/alreadyStarted), [`TorError.notStarted`](/documentation/Tor/TorError/notStarted), and [`TorError.startFailed(_:)`](/documentation/Tor/TorError/startFailed(_:)); **Control protocol** covers [`TorError.controlUnavailable`](/documentation/Tor/TorError/controlUnavailable), [`TorError.controlAuthFailed(_:)`](/documentation/Tor/TorError/controlAuthFailed(_:)), and [`TorError.controlProtocolError(code:message:)`](/documentation/Tor/TorError/controlProtocolError(code:message:)); **Onion service** covers [`TorError.invalidServiceID(_:)`](/documentation/Tor/TorError/invalidServiceID(_:)) and [`TorError.serviceAlreadyExists(_:)`](/documentation/Tor/TorError/serviceAlreadyExists(_:)); and **General** covers [`TorError.timeout`](/documentation/Tor/TorError/timeout), [`TorError.invalidResponse(_:)`](/documentation/Tor/TorError/invalidResponse(_:)), [`TorError.ioError(_:)`](/documentation/Tor/TorError/ioError(_:)), and [`TorError.resourceExhausted(_:)`](/documentation/Tor/TorError/resourceExhausted(_:)). > Note: Conformance is `Error` + `Sendable` + `Hashable` + `CustomStringConvertible`. `Hashable` is synthesised via [SE-0185](https://github.com/swiftlang/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md) across structural payloads, so two errors are equal iff both their cases and their associated strings/codes match verbatim. > Important: `TorError` does **not** yet conform to `LocalizedError`. Apple UI code that expects `error.localizedDescription` will fall back to the case name, not the human-readable ``doc://Tor/documentation/Tor/TorError/description``. Bridge explicitly via `"\(error)"` when rendering for users. ### Topics #### Lifecycle - [`TorError.alreadyStarted`](/documentation/Tor/TorError/alreadyStarted) `start()` was called on a session already in `.starting` or `.running`. - [`TorError.notStarted`](/documentation/Tor/TorError/notStarted) An operation requiring a running Tor instance was invoked against an idle/stopped/failed session. - [`TorError.startFailed(_:)`](/documentation/Tor/TorError/startFailed(_:)) Tor’s `tor_run_main()` returned non-zero during start or the start pipeline threw before the control socket became reachable. #### Control protocol - [`TorError.controlUnavailable`](/documentation/Tor/TorError/controlUnavailable) `control()` was called but no control client is bound. - [`TorError.controlAuthFailed(_:)`](/documentation/Tor/TorError/controlAuthFailed(_:)) A `AUTHENTICATE` command was rejected by Tor (reply code 515). - [`TorError.controlProtocolError(code:message:)`](/documentation/Tor/TorError/controlProtocolError(code:message:)) Tor returned a non-success reply to a control command. #### Onion services - [`TorError.invalidServiceID(_:)`](/documentation/Tor/TorError/invalidServiceID(_:)) The supplied `.onion` service ID failed validation. - [`TorError.serviceAlreadyExists(_:)`](/documentation/Tor/TorError/serviceAlreadyExists(_:)) `ADD_ONION` against a pre-existing service ID (Tor reply 550 or 554). #### General - [`TorError.timeout`](/documentation/Tor/TorError/timeout) A bounded wait elapsed without the awaited condition being met. - [`TorError.invalidResponse(_:)`](/documentation/Tor/TorError/invalidResponse(_:)) A control-protocol reply or async event could not be parsed. - [`TorError.ioError(_:)`](/documentation/Tor/TorError/ioError(_:)) A POSIX I/O operation against the control socket or data directory failed. - [`TorError.resourceExhausted(_:)`](/documentation/Tor/TorError/resourceExhausted(_:)) Tor reported resource exhaustion (Tor reply 451) — out of file descriptors, memory, or entry guards. ### Rendering - [`description`](/documentation/Tor/TorError/description) Human-readable, stable string representation of this error. ```