Shalon

public class Shalon : NSObject, StreamDelegate

With this class you can connect to a target through a Shalon proxy. Connections to the proxy and connections to the target will each be encrypted using TLS. This means that your ISP or other people in your network cannot observe to which target you connect, because they only see connections to the proxy. The proxy itself does not see the content of your requests to the target. The target will only see the proxy’s IP address (except if the IP address is otherwise embedded into the request).

This implementation supports multiple hops. Simply add other layers.

In order to use Shalon proxies with your URLSession connections, please take look at ShalonURLProtocol.

Examples

let proxy1 = Target(withHostname: "shalon1.jondonym.net", andPort: 443)!
let proxy2 = Target(withHostname: "shalon2.jondonym.net", andPort: 443)!
let proxy3 = Target(withHostname: "shalon3.jondonym.net", andPort: 443)!
let target = Target(withHostname: "www.example.com", andPort: 443)!

let shalon = Shalon(withTarget: target)

shalon.addLayer(proxy3)
shalon.addLayer(proxy2)
shalon.addLayer(proxy1)

shalon.issue(request: Request(withMethod: .head, andUrl: url)!) {
    optionalResponse, optionalError in
    // TODO Do something
}

This will establish a nested tunnel, where proxy1 cannot see what the client sends to proxy2, as depicted:

client           proxy1           proxy2           proxy3          target
|                |                |                |               |
+----------------+                |                |               |
| CONNECT proxy2 |                |                |               |
+---------------------------------+                |               |
|                  CONNECT proxy3 |                |               |
+--------------------------------------------------+               |
|                                   CONNECT proxy4 |               |
+------------------------------------------------------------------+
|                                                    HEAD /        |
+------------------------------------------------------------------+
|                                                  |               |
+--------------------------------------------------+               |
|                                 |                |               |
+---------------------------------+                |               |
|                |                |                |               |
+----------------+                |                |               |
|                |                |                |               |
  • A helper type for our callbacks, a function that gets either a HTTP response or an error.

    Declaration

    Swift

    public typealias CompletionHandler = (Http.Response?, Error?) -> Void
  • Construct a Shalon object with a given target. After calling this, proxies can be added by calling addLayer(_:).

    Warning

    If no layer is added, a direct connection will be made. Which means that the IP address of the current device will be visible to the target.

    Declaration

    Swift

    public init(withTarget target: Target)

    Parameters

    target

    The address of the server, to which requests should be issued.

  • This adds a proxy, which is connected before each other layer that was previously added, i.e., the last layer added will be the layer the initial conenction is made to.

    Declaration

    Swift

    public func addLayer(_ target: Target)

    Parameters

    target

    A proxy address.

  • Issue an HTTP request. The request is send through a TLS tunnel via proxy servers added with addLayer(_:).

    Warning

    If no layer was added with addLayer(_:), a direct connection to the target will be established. Which means that the IP address of the current device will be visible to the target.

    Postcondition

    Either the response or the error parameter of the completionHandler is set, the other one is nil.

    Declaration

    Swift

    public func issue(request: Http.Request, completionHandler: @escaping CompletionHandler)

    Parameters

    request

    The HTTP request.

    completionHandler

    A callback function. Its parameters are either an optional HTTP response or an error.