Skip to content

A secure, peer-to-peer tunnel using Bonjour and the Network framework

License

Notifications You must be signed in to change notification settings

valentinradu/swift-peer-tunnel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PeerTunnel

A secure, peer-to-peer tunnel using Bonjour and the Network framework.

Installation

Via SPM:

dependencies: [
    // ..
    .package(url: "https://github.com/valentinradu/swift-peer-tunnel.git", from: .init(0, 0, 1))
],
// ..
targets: [
    .target(
        // ..
        dependencies: [
            .product(name: "PeerTunnel", package: "swift-peer-tunnel")
        ]
    )
]

Usage

PeerTunnel enables communication between two processes through Bonjour. To establish a connection, we first have to advertise a service by providing the service name, password required to join, and message type.

/// `HelloPeerMessageKind` will be passed between our two peers 
enum HelloPeerMessageKind: UInt32, PeerMessageKindProtocol {
    case hello
}

// `PeerClamant` advertises `hello-service` over the network using Bonjour
let peerA = try PeerClamant<TestPeerMessageKind>(serviceName: "hello-service",
                                                 password: "password")
await peerA.listen()

// Then waits until the first peer connects 
let connectionA = peerA.waitForConnection()

// Once we have a connection, we can use it to send and receive data
connectionA.send(messageKind: .hello, data: Data())

On the other side, we try to find the service and connect to it.

/// `HelloPeerMessageKind` needs to be declared here as well and it has to match the 
/// declaration on the clamant's side.
enum HelloPeerMessageKind: UInt32, PeerMessageKindProtocol {
    case hello
}

// `PeerSuppliant` looks for `hello-service` via Bonjour
let peerB = PeerSuppliant<TestPeerMessageKind>(targetService: "hello-service",
                                               password: "password")
await peerB.discover()

// Then waits until it finds the service
let connectionB = try await peerB.waitForConnection()

// Once we have a connection, we can use it to send and receive data
for await message in connectionB.messages.values {
    print(message.kind)
}

Security

PeerTunnel generates a pre-shared key from the provided password using the TLS_AES_128_GCM_SHA256 cipher suite. Network.framework handles all the lower-level encrypting/decrypting functionality following industry standards.

If you plan to use PeerTunnel for security-critical applications, we recommend auditing the code first.

About

A secure, peer-to-peer tunnel using Bonjour and the Network framework

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages