diff --git a/.github/actions/archive/action.yml b/.github/actions/archive/action.yml
index f33717e..c34bd3c 100644
--- a/.github/actions/archive/action.yml
+++ b/.github/actions/archive/action.yml
@@ -29,9 +29,6 @@ runs:
xcodebuild archive \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
- -skipPackagePluginValidation \
- -skipMacroValidation \
- -onlyUsePackageVersionsFromResolvedFile \
-authenticationKeyID ${{ inputs.app-store-key-id }} \
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
diff --git a/.github/actions/build-for-testing/action.yml b/.github/actions/build-for-testing/action.yml
index 2c66963..ce91b43 100644
--- a/.github/actions/build-for-testing/action.yml
+++ b/.github/actions/build-for-testing/action.yml
@@ -24,7 +24,6 @@ runs:
path: |
Apple/PackageCache
Apple/SourcePackages
- Apple/DerivedData
key: ${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }}
restore-keys: |
${{ runner.os }}-${{ inputs.scheme }}-
@@ -34,18 +33,17 @@ runs:
run: |
echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
- xcodebuild build-for-testing \
+ xcodebuild clean build-for-testing \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
- -skipPackagePluginValidation \
- -skipMacroValidation \
- -onlyUsePackageVersionsFromResolvedFile \
-authenticationKeyID ${{ inputs.app-store-key-id }} \
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
+ -onlyUsePackageVersionsFromResolvedFile \
-clonedSourcePackagesDirPath SourcePackages \
-packageCachePath $PWD/PackageCache \
- -derivedDataPath $PWD/DerivedData \
+ -skipPackagePluginValidation \
+ -skipMacroValidation \
-scheme '${{ inputs.scheme }}' \
-destination '${{ inputs.destination }}' \
-resultBundlePath BuildResults.xcresult
diff --git a/.github/actions/export/action.yml b/.github/actions/export/action.yml
index 635732c..bf007a7 100644
--- a/.github/actions/export/action.yml
+++ b/.github/actions/export/action.yml
@@ -37,9 +37,6 @@ runs:
-exportArchive \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
- -skipPackagePluginValidation \
- -skipMacroValidation \
- -onlyUsePackageVersionsFromResolvedFile \
-authenticationKeyID ${{ inputs.app-store-key-id }} \
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
diff --git a/.github/actions/notarize/action.yml b/.github/actions/notarize/action.yml
deleted file mode 100644
index 739e9ea..0000000
--- a/.github/actions/notarize/action.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: Notarize
-inputs:
- app-store-key:
- description: App Store key in PEM PKCS#8 format
- required: true
- app-store-key-id:
- description: App Store key ID
- required: true
- app-store-key-issuer-id:
- description: App Store key issuer ID
- required: true
- archive-path:
- description: Xcode archive path
- required: true
-outputs:
- notarized-app:
- description: The compressed and notarized app
- value: ${{ steps.notarize.outputs.notarized-app }}
-runs:
- using: composite
- steps:
- - id: notarize
- shell: bash
- run: |
- echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
-
- echo '{"destination":"upload","method":"developer-id"}' \
- | plutil -convert xml1 -o ExportOptions.plist -
-
- xcodebuild \
- -exportArchive \
- -allowProvisioningUpdates \
- -allowProvisioningDeviceRegistration \
- -authenticationKeyID ${{ inputs.app-store-key-id }} \
- -authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
- -authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
- -archivePath '${{ inputs.archive-path }}' \
- -exportOptionsPlist ExportOptions.plist
-
- until xcodebuild \
- -exportNotarizedApp \
- -allowProvisioningUpdates \
- -allowProvisioningDeviceRegistration \
- -authenticationKeyID ${{ inputs.app-store-key-id }} \
- -authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
- -authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
- -archivePath '${{ inputs.archive-path }}' \
- -exportPath Release
- do
- echo "Failed to export app, trying again in 10s..."
- sleep 10
- done
-
- tar --options xz:compression-level=9 -C Release -cJvf Wallet.txz ./
- echo "notarized-app=Wallet.txz" >> $GITHUB_OUTPUT
-
- rm -rf AuthKey_${{ inputs.app-store-key-id }}.p8 Release ExportOptions.plist
diff --git a/.github/workflows/build-appimage.yml b/.github/workflows/build-appimage.yml
deleted file mode 100644
index ef5c525..0000000
--- a/.github/workflows/build-appimage.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Build AppImage
-on:
- push:
- branches: [main]
- pull_request:
-jobs:
- appimage:
- name: Build AppImage
- runs-on: ubuntu-latest
- container: docker
- steps:
- - uses: actions/checkout@v4
- - name: Build AppImage
- run: |
- docker build -t appimage-builder . -f burrow-gtk/build-aux/Dockerfile
- docker create --name temp appimage-builder
- docker cp temp:/app/burrow-gtk/build-appimage/Burrow-x86_64.AppImage .
- docker rm temp
- - uses: actions/upload-artifact@v4
- with:
- name: AppImage
- path: Burrow-x86_64.AppImage
-
diff --git a/.github/workflows/build-apple.yml b/.github/workflows/build-apple.yml
index 19ef417..da0f56a 100644
--- a/.github/workflows/build-apple.yml
+++ b/.github/workflows/build-apple.yml
@@ -12,7 +12,7 @@ concurrency:
jobs:
build:
name: Build App (${{ matrix.platform }})
- runs-on: macos-14
+ runs-on: macos-13
strategy:
fail-fast: false
matrix:
diff --git a/.github/workflows/build-flatpak.yml b/.github/workflows/build-flatpak.yml
index d74eec3..e0e804e 100644
--- a/.github/workflows/build-flatpak.yml
+++ b/.github/workflows/build-flatpak.yml
@@ -1,4 +1,7 @@
-on: workflow_dispatch
+on:
+ push:
+ branches: [main]
+ pull_request:
name: Build Flatpak
jobs:
flatpak:
diff --git a/.github/workflows/release-apple.yml b/.github/workflows/release-apple.yml
index 6164ea6..3ea185d 100644
--- a/.github/workflows/release-apple.yml
+++ b/.github/workflows/release-apple.yml
@@ -1,27 +1,26 @@
name: Build Apple Release
on:
- pull_request:
- branches:
- - "*"
+ release:
+ types:
+ - created
jobs:
build:
name: Build ${{ matrix.configuration['platform'] }} Release
- runs-on: macos-14
+ runs-on: macos-13
strategy:
fail-fast: false
matrix:
configuration:
- - destination: generic/platform=iOS
+ - scheme: App (iOS)
+ destination: generic/platform=iOS
platform: iOS
+ method: ad-hoc
artifact-file: Apple/Release/Burrow.ipa
- rust-targets:
- - aarch64-apple-ios
- - destination: generic/platform=macOS
+ - scheme: App (macOS)
+ destination: generic/platform=macOS
platform: macOS
+ method: mac-application
artifact-file: Burrow.app.txz
- rust-targets:
- - x86_64-apple-darwin
- - aarch64-apple-darwin
env:
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
steps:
@@ -35,36 +34,32 @@ jobs:
with:
certificate: ${{ secrets.DEVELOPER_CERT }}
password: ${{ secrets.DEVELOPER_CERT_PASSWORD }}
- - name: Install Rust
- uses: dtolnay/rust-toolchain@stable
- with:
- targets: ${{ join(matrix.rust-targets, ', ') }}
- name: Archive
uses: ./.github/actions/archive
with:
- scheme: App
+ scheme: ${{ matrix.configuration['scheme'] }}
destination: ${{ matrix.configuration['destination'] }}
app-store-key: ${{ secrets.APPSTORE_KEY }}
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
archive-path: Burrow.xcarchive
- - name: Upload
+ - name: Export Locally
uses: ./.github/actions/export
with:
- method: app-store-connect
- destination: upload
+ method: ${{ matrix.configuration['method'] }}
+ destination: export
app-store-key: ${{ secrets.APPSTORE_KEY }}
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
archive-path: Burrow.xcarchive
export-path: Release
- - name: Notarize
+ - name: Compress
if: ${{ matrix.configuration['platform'] == 'macOS' }}
- uses: ./.github/actions/notarize
+ shell: bash
+ run: tar --options xz:compression-level=9 -C Apple/Release -cJf Burrow.app.txz ./
+ - name: Attach Artifact
+ uses: SierraSoftworks/gh-releases@v1.0.6
with:
- app-store-key: ${{ secrets.APPSTORE_KEY }}
- app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
- app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
- archive-path: Burrow.xcarchive
- product-name: Burrow.app
-
+ token: ${{ secrets.GITHUB_TOKEN }}
+ overwrite: 'false'
+ files: ${{ matrix.configuration['artifact-file'] }}
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 22ef035..d609718 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -46,6 +46,7 @@ opt_in_rules:
- multiline_parameters
- multiline_parameters_brackets
- no_extension_access_modifier
+- no_grouping_extension
- nslocalizedstring_key
- nslocalizedstring_require_bundle
- number_separator
@@ -75,7 +76,9 @@ opt_in_rules:
- sorted_first_last
- sorted_imports
- static_operator
+- strict_fileprivate
- strong_iboutlet
+- switch_case_on_newline
- test_case_accessibility
- toggle_bool
- trailing_closure
@@ -94,5 +97,3 @@ disabled_rules:
- force_try
- nesting
- todo
-- trailing_comma
-- switch_case_on_newline
diff --git a/Apple/App/App.xcconfig b/Apple/App/App.xcconfig
index 4e42ddc..1d63205 100644
--- a/Apple/App/App.xcconfig
+++ b/Apple/App/App.xcconfig
@@ -11,12 +11,7 @@ INFOPLIST_KEY_UIStatusBarStyle[sdk=iphone*] = UIStatusBarStyleDefault
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
TARGETED_DEVICE_FAMILY[sdk=iphone*] = 1,2
-EXCLUDED_SOURCE_FILE_NAMES = MainMenu.xib
-EXCLUDED_SOURCE_FILE_NAMES[sdk=macosx*] =
-INFOPLIST_KEY_LSUIElement[sdk=macosx*] = YES
-INFOPLIST_KEY_NSMainNibFile[sdk=macosx*] = MainMenu
-INFOPLIST_KEY_NSPrincipalClass[sdk=macosx*] = NSApplication
INFOPLIST_KEY_LSApplicationCategoryType[sdk=macosx*] = public.app-category.utilities
CODE_SIGN_ENTITLEMENTS = App/App-iOS.entitlements
diff --git a/Apple/App/AppDelegate.swift b/Apple/App/AppDelegate.swift
index 6085d85..f42b52f 100644
--- a/Apple/App/AppDelegate.swift
+++ b/Apple/App/AppDelegate.swift
@@ -3,7 +3,6 @@ import AppKit
import SwiftUI
@MainActor
-@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
private let quitItem: NSMenuItem = {
let quitItem = NSMenuItem(
@@ -17,7 +16,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}()
private let toggleItem: NSMenuItem = {
- let toggleView = NSHostingView(rootView: MenuItemToggleView())
+ let toggleView = NSHostingView(rootView: MenuItemToggleView(tunnel: BurrowApp.tunnel))
toggleView.frame.size = CGSize(width: 300, height: 32)
toggleView.autoresizingMask = [.width]
diff --git a/Apple/App/Assets.xcassets/HackClub.colorset/Contents.json b/Apple/App/Assets.xcassets/HackClub.colorset/Contents.json
deleted file mode 100644
index 911b4b1..0000000
--- a/Apple/App/Assets.xcassets/HackClub.colorset/Contents.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "colors" : [
- {
- "color" : {
- "color-space" : "srgb",
- "components" : {
- "alpha" : "1.000",
- "blue" : "0x50",
- "green" : "0x37",
- "red" : "0xEC"
- }
- },
- "idiom" : "universal"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Apple/App/Assets.xcassets/HackClub.imageset/Contents.json b/Apple/App/Assets.xcassets/HackClub.imageset/Contents.json
deleted file mode 100644
index ddd0664..0000000
--- a/Apple/App/Assets.xcassets/HackClub.imageset/Contents.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "images" : [
- {
- "filename" : "flag-standalone-wtransparent.pdf",
- "idiom" : "universal"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Apple/App/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf b/Apple/App/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf
deleted file mode 100644
index 1506fe9..0000000
Binary files a/Apple/App/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf and /dev/null differ
diff --git a/Apple/App/Assets.xcassets/WireGuard.colorset/Contents.json b/Apple/App/Assets.xcassets/WireGuard.colorset/Contents.json
deleted file mode 100644
index 092ec69..0000000
--- a/Apple/App/Assets.xcassets/WireGuard.colorset/Contents.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "colors" : [
- {
- "color" : {
- "color-space" : "srgb",
- "components" : {
- "alpha" : "1.000",
- "blue" : "0x1A",
- "green" : "0x17",
- "red" : "0x88"
- }
- },
- "idiom" : "universal"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Apple/App/Assets.xcassets/WireGuard.imageset/Contents.json b/Apple/App/Assets.xcassets/WireGuard.imageset/Contents.json
deleted file mode 100644
index e7fe15a..0000000
--- a/Apple/App/Assets.xcassets/WireGuard.imageset/Contents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "images" : [
- {
- "filename" : "WireGuard.svg",
- "idiom" : "universal"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- },
- "properties" : {
- "preserves-vector-representation" : true
- }
-}
diff --git a/Apple/App/Assets.xcassets/WireGuard.imageset/WireGuard.svg b/Apple/App/Assets.xcassets/WireGuard.imageset/WireGuard.svg
deleted file mode 100644
index 9520f89..0000000
--- a/Apple/App/Assets.xcassets/WireGuard.imageset/WireGuard.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Apple/App/Assets.xcassets/WireGuardTitle.imageset/Contents.json b/Apple/App/Assets.xcassets/WireGuardTitle.imageset/Contents.json
deleted file mode 100644
index 782dd12..0000000
--- a/Apple/App/Assets.xcassets/WireGuardTitle.imageset/Contents.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "images" : [
- {
- "filename" : "WireGuardTitle.svg",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
diff --git a/Apple/App/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg b/Apple/App/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg
deleted file mode 100644
index 64946da..0000000
--- a/Apple/App/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/Apple/App/BurrowApp.swift b/Apple/App/BurrowApp.swift
index 21ebf84..e8aed86 100644
--- a/Apple/App/BurrowApp.swift
+++ b/Apple/App/BurrowApp.swift
@@ -1,13 +1,21 @@
import SwiftUI
-#if !os(macOS)
-@MainActor
@main
+@MainActor
struct BurrowApp: App {
+ static let tunnel = Tunnel { manager, proto in
+ proto.serverAddress = "hackclub.com"
+ manager.localizedDescription = "Burrow"
+ }
+
+ #if os(macOS)
+ @NSApplicationDelegateAdaptor(AppDelegate.self)
+ var delegate
+ #endif
+
var body: some Scene {
WindowGroup {
- BurrowView()
+ TunnelView(tunnel: Self.tunnel)
}
}
}
-#endif
diff --git a/Apple/App/BurrowView.swift b/Apple/App/BurrowView.swift
deleted file mode 100644
index b78b1e1..0000000
--- a/Apple/App/BurrowView.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-import SwiftUI
-
-struct BurrowView: View {
- var body: some View {
- NavigationStack {
- VStack {
- NetworkCarouselView()
- Spacer()
- TunnelStatusView()
- TunnelButton()
- .padding(.bottom)
- }
- .padding()
- .navigationTitle("Networks")
- }
- }
-}
-
-#if DEBUG
-struct NetworkView_Previews: PreviewProvider {
- static var previews: some View {
- BurrowView()
- .environment(\.tunnel, PreviewTunnel())
- }
-}
-#endif
diff --git a/Apple/App/FloatingButtonStyle.swift b/Apple/App/FloatingButtonStyle.swift
deleted file mode 100644
index 53ab5ed..0000000
--- a/Apple/App/FloatingButtonStyle.swift
+++ /dev/null
@@ -1,50 +0,0 @@
-import SwiftUI
-
-struct FloatingButtonStyle: ButtonStyle {
- static let duration = 0.08
-
- var color: Color
- var cornerRadius: CGFloat
-
- func makeBody(configuration: Configuration) -> some View {
- configuration.label
- .font(.headline)
- .foregroundColor(.white)
- .frame(minHeight: 48)
- .padding(.horizontal)
- .background(
- RoundedRectangle(cornerRadius: cornerRadius)
- .fill(
- LinearGradient(
- colors: [
- configuration.isPressed ? color.opacity(0.9) : color.opacity(0.9),
- configuration.isPressed ? color.opacity(0.9) : color
- ],
- startPoint: .init(x: 0.2, y: 0),
- endPoint: .init(x: 0.8, y: 1)
- )
- )
- .background(
- RoundedRectangle(cornerRadius: cornerRadius)
- .fill(configuration.isPressed ? .black : .white)
- )
- )
- .shadow(color: .black.opacity(configuration.isPressed ? 0.0 : 0.1), radius: 2.5, x: 0, y: 2)
- .scaleEffect(configuration.isPressed ? 0.975 : 1.0)
- .padding(.bottom, 2)
- .animation(
- configuration.isPressed ? .easeOut(duration: Self.duration) : .easeIn(duration: Self.duration),
- value: configuration.isPressed
- )
- }
-}
-
-extension ButtonStyle where Self == FloatingButtonStyle {
- static var floating: FloatingButtonStyle {
- floating()
- }
-
- static func floating(color: Color = .accentColor, cornerRadius: CGFloat = 10) -> FloatingButtonStyle {
- FloatingButtonStyle(color: color, cornerRadius: cornerRadius)
- }
-}
diff --git a/Apple/App/MainMenu.xib b/Apple/App/MainMenu.xib
deleted file mode 100644
index 8933f30..0000000
--- a/Apple/App/MainMenu.xib
+++ /dev/null
@@ -1,679 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Apple/App/Menu/MenuView.swift b/Apple/App/Menu/MenuView.swift
new file mode 100644
index 0000000..eab8da2
--- /dev/null
+++ b/Apple/App/Menu/MenuView.swift
@@ -0,0 +1,60 @@
+//
+// MenuView.swift
+// App
+//
+// Created by Thomas Stubblefield on 5/13/23.
+//
+
+import SwiftUI
+
+struct MenuItemToggleView: View {
+ var tunnel: Tunnel
+
+ var body: some View {
+ HStack {
+ Text("Burrow")
+ .font(.headline)
+ Spacer()
+ Toggle("Burrow", isOn: tunnel.isOn)
+ .labelsHidden()
+ .disabled(tunnel.isDisabled)
+ .toggleStyle(.switch)
+ }
+ .padding(.horizontal, 4)
+ .padding(10)
+ .frame(minWidth: 300, minHeight: 32, maxHeight: 32)
+ }
+}
+
+extension Tunnel {
+ var isDisabled: Bool {
+ switch self.status {
+ case .disconnected, .permissionRequired, .connected:
+ return false
+ case .unknown, .disabled, .connecting, .reasserting, .disconnecting, .invalid, .configurationReadWriteFailed:
+ return true
+ }
+ }
+
+ var isOn: Binding {
+ Binding {
+ switch self.status {
+ case .connecting, .reasserting, .connected:
+ true
+ default:
+ false
+ }
+ } set: { newValue in
+ switch (self.status, newValue) {
+ case (.permissionRequired, true):
+ Task { try await self.configure() }
+ case (.disconnected, true):
+ try? self.start()
+ case (.connected, false):
+ self.stop()
+ default:
+ return
+ }
+ }
+ }
+}
diff --git a/Apple/App/MenuItemToggleView.swift b/Apple/App/MenuItemToggleView.swift
deleted file mode 100644
index 07db51d..0000000
--- a/Apple/App/MenuItemToggleView.swift
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// MenuItemToggleView.swift
-// App
-//
-// Created by Thomas Stubblefield on 5/13/23.
-//
-
-import SwiftUI
-
-struct MenuItemToggleView: View {
- @Environment(\.tunnel)
- var tunnel: Tunnel
-
- var body: some View {
- HStack {
- VStack(alignment: .leading) {
- Text("Burrow")
- .font(.headline)
- Text(tunnel.status.description)
- .font(.subheadline)
- }
- Spacer()
- Toggle(isOn: tunnel.toggleIsOn) {
- }
- .disabled(tunnel.toggleDisabled)
- .toggleStyle(.switch)
- }
- .accessibilityElement(children: .combine)
- .padding(.horizontal, 4)
- .padding(10)
- .frame(minWidth: 300, minHeight: 32, maxHeight: 32)
- }
-}
-
-extension Tunnel {
- fileprivate var toggleDisabled: Bool {
- switch status {
- case .disconnected, .permissionRequired, .connected, .disconnecting:
- false
- case .unknown, .disabled, .connecting, .reasserting, .invalid, .configurationReadWriteFailed:
- true
- }
- }
-
- var toggleIsOn: Binding {
- Binding {
- switch status {
- case .connecting, .reasserting, .connected:
- true
- default:
- false
- }
- } set: { newValue in
- switch (status, newValue) {
- case (.permissionRequired, true):
- enable()
- case (_, true):
- start()
- case (_, false):
- stop()
- }
- }
- }
-}
diff --git a/Apple/App/NetworkExtensionTunnel.swift b/Apple/App/NetworkExtensionTunnel.swift
deleted file mode 100644
index 08002de..0000000
--- a/Apple/App/NetworkExtensionTunnel.swift
+++ /dev/null
@@ -1,167 +0,0 @@
-import BurrowShared
-import NetworkExtension
-
-@Observable
-class NetworkExtensionTunnel: Tunnel {
- @MainActor private(set) var status: TunnelStatus = .unknown
- private var error: NEVPNError?
-
- private let logger = Logger.logger(for: Tunnel.self)
- private let bundleIdentifier: String
- private var tasks: [Task] = []
-
- // Each manager corresponds to one entry in the Settings app.
- // Our goal is to maintain a single manager, so we create one if none exist and delete any extra.
- private var managers: [NEVPNManager]? {
- didSet { Task { await updateStatus() } }
- }
-
- private var currentStatus: TunnelStatus {
- guard let managers = managers else {
- guard let error = error else {
- return .unknown
- }
-
- switch error.code {
- case .configurationReadWriteFailed:
- return .configurationReadWriteFailed
- default:
- return .unknown
- }
- }
-
- guard let manager = managers.first else {
- return .permissionRequired
- }
-
- guard manager.isEnabled else {
- return .disabled
- }
-
- return manager.connection.tunnelStatus
- }
-
- convenience init() {
- self.init(Constants.networkExtensionBundleIdentifier)
- }
-
- init(_ bundleIdentifier: String) {
- self.bundleIdentifier = bundleIdentifier
-
- let center = NotificationCenter.default
- let configurationChanged = Task { [weak self] in
- for try await _ in center.notifications(named: .NEVPNConfigurationChange).map({ _ in () }) {
- await self?.update()
- }
- }
- let statusChanged = Task { [weak self] in
- for try await _ in center.notifications(named: .NEVPNStatusDidChange).map({ _ in () }) {
- await self?.updateStatus()
- }
- }
- tasks = [configurationChanged, statusChanged]
-
- Task { await update() }
- }
-
- private func update() async {
- do {
- managers = try await NETunnelProviderManager.managers
- await self.updateStatus()
- } catch let vpnError as NEVPNError {
- error = vpnError
- } catch {
- logger.error("Failed to update VPN configurations: \(error)")
- }
- }
-
- private func updateStatus() async {
- await MainActor.run {
- status = currentStatus
- }
- }
-
- func configure() async throws {
- if managers == nil {
- await update()
- }
-
- guard let managers = managers else { return }
-
- if managers.count > 1 {
- try await withThrowingTaskGroup(of: Void.self, returning: Void.self) { group in
- for manager in managers.suffix(from: 1) {
- group.addTask { try await manager.remove() }
- }
- try await group.waitForAll()
- }
- }
-
- guard managers.isEmpty else { return }
-
- let manager = NETunnelProviderManager()
- manager.localizedDescription = "Burrow"
-
- let proto = NETunnelProviderProtocol()
- proto.providerBundleIdentifier = bundleIdentifier
- proto.serverAddress = "hackclub.com"
-
- manager.protocolConfiguration = proto
- try await manager.save()
- }
-
- func start() {
- guard let manager = managers?.first else { return }
- Task {
- do {
- if !manager.isEnabled {
- manager.isEnabled = true
- try await manager.save()
- }
- try manager.connection.startVPNTunnel()
- } catch {
- logger.error("Failed to start: \(error)")
- }
- }
- }
-
- func stop() {
- guard let manager = managers?.first else { return }
- manager.connection.stopVPNTunnel()
- }
-
- func enable() {
- Task {
- do {
- try await configure()
- } catch {
- logger.error("Failed to enable: \(error)")
- }
- }
- }
-
- deinit {
- tasks.forEach { $0.cancel() }
- }
-}
-
-extension NEVPNConnection {
- fileprivate var tunnelStatus: TunnelStatus {
- switch status {
- case .connected:
- .connected(connectedDate!)
- case .connecting:
- .connecting
- case .disconnecting:
- .disconnecting
- case .disconnected:
- .disconnected
- case .reasserting:
- .reasserting
- case .invalid:
- .invalid
- @unknown default:
- .unknown
- }
- }
-}
diff --git a/Apple/App/NetworkView.swift b/Apple/App/NetworkView.swift
deleted file mode 100644
index 290254c..0000000
--- a/Apple/App/NetworkView.swift
+++ /dev/null
@@ -1,88 +0,0 @@
-import SwiftUI
-
-struct NetworkView: View {
- var color: Color
- var content: () -> Content
-
- private var gradient: LinearGradient {
- LinearGradient(
- colors: [
- color.opacity(0.8),
- color
- ],
- startPoint: .init(x: 0.2, y: 0),
- endPoint: .init(x: 0.8, y: 1)
- )
- }
-
- var body: some View {
- content()
- .frame(maxWidth: .infinity, minHeight: 175, maxHeight: 175)
- .background(
- RoundedRectangle(cornerRadius: 10)
- .fill(gradient)
- .background(
- RoundedRectangle(cornerRadius: 10)
- .fill(.white)
- )
- )
- .shadow(color: .black.opacity(0.1), radius: 3.0, x: 0, y: 2)
- }
-}
-
-struct AddNetworkView: View {
- var body: some View {
- Text("Add Network")
- .frame(maxWidth: .infinity, minHeight: 175, maxHeight: 175)
- .background(
- RoundedRectangle(cornerRadius: 10)
- .stroke(style: .init(lineWidth: 2, dash: [6]))
- )
- }
-}
-
-extension NetworkView where Content == AnyView {
- init(network: any Network) {
- color = network.backgroundColor
- content = { AnyView(network.label) }
- }
-}
-
-struct NetworkCarouselView: View {
- var networks: [any Network] = [
- HackClub(id: "1"),
- HackClub(id: "2"),
- WireGuard(id: "4"),
- HackClub(id: "5"),
- ]
-
- var body: some View {
- ScrollView(.horizontal) {
- LazyHStack {
- ForEach(networks, id: \.id) { network in
- NetworkView(network: network)
- .containerRelativeFrame(.horizontal, count: 10, span: 7, spacing: 0, alignment: .center)
- .scrollTransition(.interactive, axis: .horizontal) { content, phase in
- content
- .scaleEffect(1.0 - abs(phase.value) * 0.1)
- }
- }
- AddNetworkView()
- }
- .scrollTargetLayout()
- }
- .scrollClipDisabled()
- .scrollIndicators(.hidden)
- .defaultScrollAnchor(.center)
- .scrollTargetBehavior(.viewAligned)
- .containerRelativeFrame(.horizontal)
- }
-}
-
-#if DEBUG
-struct NetworkCarouselView_Previews: PreviewProvider {
- static var previews: some View {
- NetworkCarouselView()
- }
-}
-#endif
diff --git a/Apple/App/Networks/HackClub.swift b/Apple/App/Networks/HackClub.swift
deleted file mode 100644
index f7df674..0000000
--- a/Apple/App/Networks/HackClub.swift
+++ /dev/null
@@ -1,23 +0,0 @@
-import SwiftUI
-
-struct HackClub: Network {
- var id: String
- var backgroundColor: Color { .init("HackClub") }
-
- var label: some View {
- GeometryReader { reader in
- VStack(alignment: .leading) {
- Image("HackClub")
- .resizable()
- .aspectRatio(contentMode: .fit)
- .frame(height: reader.size.height / 4)
- Spacer()
- Text("@conradev")
- .foregroundStyle(.white)
- .font(.body.monospaced())
- }
- .padding()
- .frame(maxWidth: .infinity)
- }
- }
-}
diff --git a/Apple/App/Networks/Network.swift b/Apple/App/Networks/Network.swift
deleted file mode 100644
index d441d24..0000000
--- a/Apple/App/Networks/Network.swift
+++ /dev/null
@@ -1,10 +0,0 @@
-import SwiftUI
-
-protocol Network {
- associatedtype Label: View
-
- var id: String { get }
- var backgroundColor: Color { get }
-
- var label: Label { get }
-}
diff --git a/Apple/App/Networks/WireGuard.swift b/Apple/App/Networks/WireGuard.swift
deleted file mode 100644
index 499288a..0000000
--- a/Apple/App/Networks/WireGuard.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-import SwiftUI
-
-struct WireGuard: Network {
- var id: String
- var backgroundColor: Color { .init("WireGuard") }
-
- var label: some View {
- GeometryReader { reader in
- VStack(alignment: .leading) {
- HStack {
- Image("WireGuard")
- .resizable()
- .aspectRatio(contentMode: .fit)
- Image("WireGuardTitle")
- .resizable()
- .aspectRatio(contentMode: .fit)
- .frame(width: reader.size.width / 2)
- Spacer()
- }
- .frame(maxWidth: .infinity, maxHeight: reader.size.height / 4)
- Spacer()
- Text("@conradev")
- .foregroundStyle(.white)
- .font(.body.monospaced())
- }
- .padding()
- .frame(maxWidth: .infinity)
- }
- }
-}
diff --git a/Apple/App/Status.swift b/Apple/App/Status.swift
new file mode 100644
index 0000000..c08cdd1
--- /dev/null
+++ b/Apple/App/Status.swift
@@ -0,0 +1,42 @@
+import Foundation
+import NetworkExtension
+
+extension Tunnel {
+ enum Status: CustomStringConvertible, Equatable, Hashable {
+ case unknown
+ case permissionRequired
+ case disabled
+ case connecting
+ case connected(Date)
+ case disconnecting
+ case disconnected
+ case reasserting
+ case invalid
+ case configurationReadWriteFailed
+
+ var description: String {
+ switch self {
+ case .unknown:
+ return "Unknown"
+ case .permissionRequired:
+ return "Permission Required"
+ case .disconnected:
+ return "Disconnected"
+ case .disabled:
+ return "Disabled"
+ case .connecting:
+ return "Connecting"
+ case .connected:
+ return "Connected"
+ case .disconnecting:
+ return "Disconnecting"
+ case .reasserting:
+ return "Reasserting"
+ case .invalid:
+ return "Invalid"
+ case .configurationReadWriteFailed:
+ return "System Error"
+ }
+ }
+ }
+}
diff --git a/Apple/App/Tunnel.swift b/Apple/App/Tunnel.swift
index 8db366f..5542170 100644
--- a/Apple/App/Tunnel.swift
+++ b/Apple/App/Tunnel.swift
@@ -1,50 +1,146 @@
+import BurrowShared
+import NetworkExtension
import SwiftUI
-protocol Tunnel {
- var status: TunnelStatus { get }
-
- func start()
- func stop()
- func enable()
-}
-
-enum TunnelStatus: Equatable, Hashable {
- case unknown
- case permissionRequired
- case disabled
- case connecting
- case connected(Date)
- case disconnecting
- case disconnected
- case reasserting
- case invalid
- case configurationReadWriteFailed
-}
-
-struct TunnelKey: EnvironmentKey {
- static let defaultValue: any Tunnel = NetworkExtensionTunnel()
-}
-
-extension EnvironmentValues {
- var tunnel: any Tunnel {
- get { self[TunnelKey.self] }
- set { self[TunnelKey.self] = newValue }
- }
-}
-
-#if DEBUG
@Observable
-class PreviewTunnel: Tunnel {
- var status: TunnelStatus = .permissionRequired
+class Tunnel {
+ private(set) var status: Status = .unknown
+ private var error: NEVPNError?
- func start() {
- status = .connected(.now)
+ private let logger = Logger.logger(for: Tunnel.self)
+ private let bundleIdentifier: String
+ private let configure: (NETunnelProviderManager, NETunnelProviderProtocol) -> Void
+ private var tasks: [Task] = []
+
+ // Each manager corresponds to one entry in the Settings app.
+ // Our goal is to maintain a single manager, so we create one if none exist and delete extra if there are any.
+ private var managers: [NEVPNManager]? {
+ didSet { status = currentStatus }
}
+
+ private var currentStatus: Status {
+ guard let managers = managers else {
+ guard let error = error else {
+ return .unknown
+ }
+
+ switch error.code {
+ case .configurationReadWriteFailed:
+ return .configurationReadWriteFailed
+ default:
+ return .unknown
+ }
+ }
+
+ guard let manager = managers.first else {
+ return .permissionRequired
+ }
+
+ guard manager.isEnabled else {
+ return .disabled
+ }
+
+ return manager.connection.tunnelStatus
+ }
+
+ convenience init(configure: @escaping (NETunnelProviderManager, NETunnelProviderProtocol) -> Void) {
+ self.init("com.hackclub.burrow.network", configure: configure)
+ }
+
+ init(_ bundleIdentifier: String, configure: @escaping (NETunnelProviderManager, NETunnelProviderProtocol) -> Void) {
+ self.bundleIdentifier = bundleIdentifier
+ self.configure = configure
+
+ let center = NotificationCenter.default
+ let configurationChanged = Task {
+ for try await _ in center.notifications(named: .NEVPNConfigurationChange).map({ _ in () }) {
+ await update()
+ }
+ }
+ let statusChanged = Task {
+ for try await _ in center.notifications(named: .NEVPNStatusDidChange).map({ _ in () }) {
+ await MainActor.run {
+ status = currentStatus
+ }
+ }
+ }
+ tasks = [configurationChanged, statusChanged]
+
+ Task { await update() }
+ }
+
+ private func update() async {
+ do {
+ let updated = try await NETunnelProviderManager.managers
+ await MainActor.run {
+ managers = updated
+ }
+ } catch let vpnError as NEVPNError {
+ error = vpnError
+ } catch {
+ logger.error("Failed to update VPN configurations: \(error)")
+ }
+ }
+
+ func configure() async throws {
+ if managers == nil {
+ await update()
+ }
+
+ guard let managers = managers else { return }
+
+ if managers.count > 1 {
+ try await withThrowingTaskGroup(of: Void.self, returning: Void.self) { group in
+ for manager in managers.suffix(from: 1) {
+ group.addTask { try await manager.remove() }
+ }
+ try await group.waitForAll()
+ }
+ }
+
+ if managers.isEmpty {
+ let manager = NETunnelProviderManager()
+ let proto = NETunnelProviderProtocol()
+ proto.providerBundleIdentifier = bundleIdentifier
+ configure(manager, proto)
+
+ manager.protocolConfiguration = proto
+ try await manager.save()
+ }
+ }
+
+ func start() throws {
+ guard let manager = managers?.first else { return }
+ try manager.connection.startVPNTunnel()
+ }
+
func stop() {
- status = .disconnected
+ guard let manager = managers?.first else { return }
+ manager.connection.stopVPNTunnel()
}
- func enable() {
- status = .disconnected
+
+ deinit {
+ tasks.forEach { $0.cancel() }
+ }
+}
+
+extension NEVPNConnection {
+ var tunnelStatus: Tunnel.Status {
+ switch status {
+ case .connected:
+ .connected(connectedDate!)
+ case .connecting:
+ .connecting
+ case .disconnecting:
+ .disconnecting
+ case .disconnected:
+ .disconnected
+ case .reasserting:
+ .reasserting
+ case .invalid:
+ .invalid
+ @unknown default:
+ .unknown
+ }
}
}
-#endif
diff --git a/Apple/App/TunnelButton.swift b/Apple/App/TunnelButton.swift
deleted file mode 100644
index df8d7e6..0000000
--- a/Apple/App/TunnelButton.swift
+++ /dev/null
@@ -1,61 +0,0 @@
-import SwiftUI
-
-struct TunnelButton: View {
- @Environment(\.tunnel)
- var tunnel: any Tunnel
-
- var body: some View {
- if let action = tunnel.action {
- Button {
- tunnel.perform(action)
- } label: {
- Text(action.description)
- }
- .padding(.horizontal)
- .buttonStyle(.floating)
- }
- }
-}
-
-extension Tunnel {
- fileprivate var action: TunnelButton.Action? {
- switch status {
- case .permissionRequired, .invalid:
- .enable
- case .disabled, .disconnecting, .disconnected:
- .start
- case .connecting, .connected, .reasserting:
- .stop
- case .unknown, .configurationReadWriteFailed:
- nil
- }
- }
-}
-
-extension TunnelButton {
- fileprivate enum Action {
- case enable
- case start
- case stop
- }
-}
-
-extension TunnelButton.Action {
- var description: LocalizedStringKey {
- switch self {
- case .enable: "Enable"
- case .start: "Start"
- case .stop: "Stop"
- }
- }
-}
-
-extension Tunnel {
- fileprivate func perform(_ action: TunnelButton.Action) {
- switch action {
- case .enable: enable()
- case .start: start()
- case .stop: stop()
- }
- }
-}
diff --git a/Apple/App/TunnelStatusView.swift b/Apple/App/TunnelStatusView.swift
deleted file mode 100644
index 3593516..0000000
--- a/Apple/App/TunnelStatusView.swift
+++ /dev/null
@@ -1,37 +0,0 @@
-import SwiftUI
-
-struct TunnelStatusView: View {
- @Environment(\.tunnel)
- var tunnel: any Tunnel
-
- var body: some View {
- Text(tunnel.status.description)
- }
-}
-
-extension TunnelStatus: CustomStringConvertible {
- var description: String {
- switch self {
- case .unknown:
- "Unknown"
- case .permissionRequired:
- "Permission Required"
- case .disconnected:
- "Disconnected"
- case .disabled:
- "Disabled"
- case .connecting:
- "Connecting…"
- case .connected:
- "Connected"
- case .disconnecting:
- "Disconnecting…"
- case .reasserting:
- "Reasserting…"
- case .invalid:
- "Invalid"
- case .configurationReadWriteFailed:
- "System Error"
- }
- }
-}
diff --git a/Apple/App/TunnelView.swift b/Apple/App/TunnelView.swift
new file mode 100644
index 0000000..dd91603
--- /dev/null
+++ b/Apple/App/TunnelView.swift
@@ -0,0 +1,34 @@
+import SwiftUI
+
+struct TunnelView: View {
+ var tunnel: Tunnel
+
+ var body: some View {
+ VStack {
+ Text(verbatim: tunnel.status.description)
+ switch tunnel.status {
+ case .connected:
+ Button("Disconnect", action: stop)
+ case .permissionRequired:
+ Button("Allow", action: configure)
+ case .disconnected:
+ Button("Start", action: start)
+ default:
+ EmptyView()
+ }
+ }
+ .padding()
+ }
+
+ private func start() {
+ try? tunnel.start()
+ }
+
+ private func stop() {
+ tunnel.stop()
+ }
+
+ private func configure() {
+ Task { try await tunnel.configure() }
+ }
+}
diff --git a/Apple/Burrow.xcodeproj/project.pbxproj b/Apple/Burrow.xcodeproj/project.pbxproj
index 8717a30..428d9ab 100644
--- a/Apple/Burrow.xcodeproj/project.pbxproj
+++ b/Apple/Burrow.xcodeproj/project.pbxproj
@@ -9,32 +9,24 @@
/* Begin PBXBuildFile section */
0B28F1562ABF463A000D44B0 /* DataTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B28F1552ABF463A000D44B0 /* DataTypes.swift */; };
0B46E8E02AC918CA00BA2A3C /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B46E8DF2AC918CA00BA2A3C /* Client.swift */; };
- 43AA26D82A10004900F14CE6 /* MenuItemToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AA26D72A10004900F14CE6 /* MenuItemToggleView.swift */; };
+ 43AA26D82A10004900F14CE6 /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AA26D72A10004900F14CE6 /* MenuView.swift */; };
D00117312B2FFFC900D87C25 /* NWConnection+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00117302B2FFFC900D87C25 /* NWConnection+Async.swift */; };
D00117332B3001A400D87C25 /* NewlineProtocolFramer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00117322B3001A400D87C25 /* NewlineProtocolFramer.swift */; };
D001173B2B30341C00D87C25 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D001173A2B30341C00D87C25 /* Logging.swift */; };
D00117442B30372900D87C25 /* libBurrowShared.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D00117382B30341C00D87C25 /* libBurrowShared.a */; };
D00117452B30372C00D87C25 /* libBurrowShared.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D00117382B30341C00D87C25 /* libBurrowShared.a */; };
D00AA8972A4669BC005C8102 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00AA8962A4669BC005C8102 /* AppDelegate.swift */; };
- D01A79312B81630D0024EC91 /* NetworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01A79302B81630D0024EC91 /* NetworkView.swift */; };
D020F65829E4A697002790F6 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D020F65729E4A697002790F6 /* PacketTunnelProvider.swift */; };
D020F65D29E4A697002790F6 /* BurrowNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
- D032E6522B8A79C20006B8AD /* HackClub.swift in Sources */ = {isa = PBXBuildFile; fileRef = D032E6512B8A79C20006B8AD /* HackClub.swift */; };
- D032E6542B8A79DA0006B8AD /* WireGuard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D032E6532B8A79DA0006B8AD /* WireGuard.swift */; };
D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */; };
- D05B9F7829E39EEC008CB1F9 /* BurrowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7729E39EEC008CB1F9 /* BurrowView.swift */; };
+ D05B9F7829E39EEC008CB1F9 /* TunnelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */; };
D05B9F7A29E39EED008CB1F9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D05B9F7929E39EED008CB1F9 /* Assets.xcassets */; };
- D05EF8C82B81818D0017AB4F /* FloatingButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05EF8C72B81818D0017AB4F /* FloatingButtonStyle.swift */; };
D08252762B5C9FC4005DA378 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08252752B5C9FC4005DA378 /* Constants.swift */; };
- D09150422B9D2AF700BE3CB0 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D09150412B9D2AF700BE3CB0 /* MainMenu.xib */; };
D0BCC5FD2A086D4700AD070D /* NetworkExtension+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BCC5FC2A086D4700AD070D /* NetworkExtension+Async.swift */; };
+ D0BCC5FF2A086E1C00AD070D /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BCC5FE2A086E1C00AD070D /* Status.swift */; };
D0BCC6082A0981FE00AD070D /* Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B98FC629FDC5B5004E7149 /* Tunnel.swift */; };
D0BCC6092A09A03E00AD070D /* libburrow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCC6032A09535900AD070D /* libburrow.a */; };
D0BCC60A2A09A0B800AD070D /* build-rust.sh in Resources */ = {isa = PBXBuildFile; fileRef = D0B98FBF29FD8072004E7149 /* build-rust.sh */; };
- D0FAB5922B818A5900F6A84B /* NetworkExtensionTunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FAB5912B818A5900F6A84B /* NetworkExtensionTunnel.swift */; };
- D0FAB5962B818B2900F6A84B /* TunnelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FAB5952B818B2900F6A84B /* TunnelButton.swift */; };
- D0FAB5982B818B8200F6A84B /* TunnelStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FAB5972B818B8200F6A84B /* TunnelStatusView.swift */; };
- D0FAB59A2B818B9600F6A84B /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FAB5992B818B9600F6A84B /* Network.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -78,7 +70,7 @@
/* Begin PBXFileReference section */
0B28F1552ABF463A000D44B0 /* DataTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTypes.swift; sourceTree = ""; };
0B46E8DF2AC918CA00BA2A3C /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = ""; };
- 43AA26D72A10004900F14CE6 /* MenuItemToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemToggleView.swift; sourceTree = ""; };
+ 43AA26D72A10004900F14CE6 /* MenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = ""; };
D00117302B2FFFC900D87C25 /* NWConnection+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NWConnection+Async.swift"; sourceTree = ""; };
D00117322B3001A400D87C25 /* NewlineProtocolFramer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewlineProtocolFramer.swift; sourceTree = ""; };
D00117382B30341C00D87C25 /* libBurrowShared.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBurrowShared.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -86,7 +78,6 @@
D00117412B30347800D87C25 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; };
D00117422B30348D00D87C25 /* Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = ""; };
D00AA8962A4669BC005C8102 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- D01A79302B81630D0024EC91 /* NetworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkView.swift; sourceTree = ""; };
D020F63D29E4A1FF002790F6 /* Identity.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Identity.xcconfig; sourceTree = ""; };
D020F64029E4A1FF002790F6 /* Compiler.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Compiler.xcconfig; sourceTree = ""; };
D020F64229E4A1FF002790F6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -101,26 +92,19 @@
D020F66729E4A95D002790F6 /* NetworkExtension-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "NetworkExtension-iOS.entitlements"; sourceTree = ""; };
D020F66829E4AA74002790F6 /* App-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "App-iOS.entitlements"; sourceTree = ""; };
D020F66929E4AA74002790F6 /* App-macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "App-macOS.entitlements"; sourceTree = ""; };
- D032E6512B8A79C20006B8AD /* HackClub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HackClub.swift; sourceTree = ""; };
- D032E6532B8A79DA0006B8AD /* WireGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuard.swift; sourceTree = ""; };
D05B9F7229E39EEC008CB1F9 /* Burrow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Burrow.app; sourceTree = BUILT_PRODUCTS_DIR; };
D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurrowApp.swift; sourceTree = ""; };
- D05B9F7729E39EEC008CB1F9 /* BurrowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurrowView.swift; sourceTree = ""; };
+ D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelView.swift; sourceTree = ""; };
D05B9F7929E39EED008CB1F9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- D05EF8C72B81818D0017AB4F /* FloatingButtonStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingButtonStyle.swift; sourceTree = ""; };
D08252742B5C9DEB005DA378 /* Constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = ""; };
D08252752B5C9FC4005DA378 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
- D09150412B9D2AF700BE3CB0 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; };
D0B98FBF29FD8072004E7149 /* build-rust.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-rust.sh"; sourceTree = ""; };
D0B98FC629FDC5B5004E7149 /* Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tunnel.swift; sourceTree = ""; };
D0B98FD829FDDB6F004E7149 /* libburrow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libburrow.h; sourceTree = ""; };
D0B98FDC29FDDDCF004E7149 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; };
D0BCC5FC2A086D4700AD070D /* NetworkExtension+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkExtension+Async.swift"; sourceTree = ""; };
+ D0BCC5FE2A086E1C00AD070D /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = ""; };
D0BCC6032A09535900AD070D /* libburrow.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libburrow.a; sourceTree = BUILT_PRODUCTS_DIR; };
- D0FAB5912B818A5900F6A84B /* NetworkExtensionTunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkExtensionTunnel.swift; sourceTree = ""; };
- D0FAB5952B818B2900F6A84B /* TunnelButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelButton.swift; sourceTree = ""; };
- D0FAB5972B818B8200F6A84B /* TunnelStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelStatusView.swift; sourceTree = ""; };
- D0FAB5992B818B9600F6A84B /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -151,6 +135,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 43AA26D62A0FFFD000F14CE6 /* Menu */ = {
+ isa = PBXGroup;
+ children = (
+ 43AA26D72A10004900F14CE6 /* MenuView.swift */,
+ );
+ path = Menu;
+ sourceTree = "";
+ };
D00117392B30341C00D87C25 /* Shared */ = {
isa = PBXGroup;
children = (
@@ -207,16 +199,6 @@
path = NetworkExtension;
sourceTree = "";
};
- D032E64D2B8A69C90006B8AD /* Networks */ = {
- isa = PBXGroup;
- children = (
- D0FAB5992B818B9600F6A84B /* Network.swift */,
- D032E6512B8A79C20006B8AD /* HackClub.swift */,
- D032E6532B8A79DA0006B8AD /* WireGuard.swift */,
- );
- path = Networks;
- sourceTree = "";
- };
D05B9F6929E39EEC008CB1F9 = {
isa = PBXGroup;
children = (
@@ -242,20 +224,14 @@
D05B9F7429E39EEC008CB1F9 /* App */ = {
isa = PBXGroup;
children = (
+ 43AA26D62A0FFFD000F14CE6 /* Menu */,
D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */,
D00AA8962A4669BC005C8102 /* AppDelegate.swift */,
- 43AA26D72A10004900F14CE6 /* MenuItemToggleView.swift */,
- D05B9F7729E39EEC008CB1F9 /* BurrowView.swift */,
- D01A79302B81630D0024EC91 /* NetworkView.swift */,
- D032E64D2B8A69C90006B8AD /* Networks */,
- D0FAB5972B818B8200F6A84B /* TunnelStatusView.swift */,
- D0FAB5952B818B2900F6A84B /* TunnelButton.swift */,
+ D05B9F7729E39EEC008CB1F9 /* TunnelView.swift */,
D0B98FC629FDC5B5004E7149 /* Tunnel.swift */,
- D0FAB5912B818A5900F6A84B /* NetworkExtensionTunnel.swift */,
+ D0BCC5FE2A086E1C00AD070D /* Status.swift */,
D0BCC5FC2A086D4700AD070D /* NetworkExtension+Async.swift */,
- D05EF8C72B81818D0017AB4F /* FloatingButtonStyle.swift */,
D05B9F7929E39EED008CB1F9 /* Assets.xcassets */,
- D09150412B9D2AF700BE3CB0 /* MainMenu.xib */,
D020F66829E4AA74002790F6 /* App-iOS.entitlements */,
D020F66929E4AA74002790F6 /* App-macOS.entitlements */,
D020F64929E4A34B002790F6 /* App.xcconfig */,
@@ -343,7 +319,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1510;
- LastUpgradeCheck = 1520;
+ LastUpgradeCheck = 1430;
TargetAttributes = {
D00117372B30341C00D87C25 = {
CreatedOnToolsVersion = 15.1;
@@ -393,7 +369,6 @@
buildActionMask = 2147483647;
files = (
D05B9F7A29E39EED008CB1F9 /* Assets.xcassets in Resources */,
- D09150422B9D2AF700BE3CB0 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -448,19 +423,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- D0FAB59A2B818B9600F6A84B /* Network.swift in Sources */,
D0BCC6082A0981FE00AD070D /* Tunnel.swift in Sources */,
- D0FAB5982B818B8200F6A84B /* TunnelStatusView.swift in Sources */,
- 43AA26D82A10004900F14CE6 /* MenuItemToggleView.swift in Sources */,
- D05B9F7829E39EEC008CB1F9 /* BurrowView.swift in Sources */,
- D0FAB5922B818A5900F6A84B /* NetworkExtensionTunnel.swift in Sources */,
- D0FAB5962B818B2900F6A84B /* TunnelButton.swift in Sources */,
+ 43AA26D82A10004900F14CE6 /* MenuView.swift in Sources */,
+ D05B9F7829E39EEC008CB1F9 /* TunnelView.swift in Sources */,
+ D0BCC5FF2A086E1C00AD070D /* Status.swift in Sources */,
D00AA8972A4669BC005C8102 /* AppDelegate.swift in Sources */,
- D05EF8C82B81818D0017AB4F /* FloatingButtonStyle.swift in Sources */,
- D032E6522B8A79C20006B8AD /* HackClub.swift in Sources */,
D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */,
- D01A79312B81630D0024EC91 /* NetworkView.swift in Sources */,
- D032E6542B8A79DA0006B8AD /* WireGuard.swift in Sources */,
D0BCC5FD2A086D4700AD070D /* NetworkExtension+Async.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -600,8 +568,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/realm/SwiftLint.git";
requirement = {
- branch = main;
- kind = branch;
+ kind = upToNextMajorVersion;
+ minimumVersion = 0.54.0;
};
};
/* End XCRemoteSwiftPackageReference section */
diff --git a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 9378372..7522840 100644
--- a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
- "revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
- "version" : "1.2.3"
+ "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a",
+ "version" : "1.2.2"
}
},
{
@@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
- "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
- "version" : "509.1.1"
+ "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
+ "version" : "509.0.2"
}
},
{
@@ -50,8 +50,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/SwiftLint.git",
"state" : {
- "branch" : "main",
- "revision" : "7595ad3fafc1a31086dc40ba01fd898bf6b42d5f"
+ "revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
+ "version" : "0.54.0"
}
},
{
@@ -68,8 +68,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/drmohundro/SWXMLHash.git",
"state" : {
- "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
- "version" : "7.0.2"
+ "revision" : "4d0f62f561458cbe1f732171e625f03195151b60",
+ "version" : "7.0.1"
}
},
{
diff --git a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme
index 670823d..c63f8e6 100644
--- a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme
+++ b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme
@@ -1,6 +1,6 @@
: Codable where T: Codable {
struct ServerConfigData: Codable {
struct InternalConfig: Codable {
- let address: [String]
+ let address: String?
let name: String?
let mtu: Int32?
}
diff --git a/Apple/NetworkExtension/PacketTunnelProvider.swift b/Apple/NetworkExtension/PacketTunnelProvider.swift
index a07daa3..9231676 100644
--- a/Apple/NetworkExtension/PacketTunnelProvider.swift
+++ b/Apple/NetworkExtension/PacketTunnelProvider.swift
@@ -6,16 +6,10 @@ import os
class PacketTunnelProvider: NEPacketTunnelProvider {
private let logger = Logger.logger(for: PacketTunnelProvider.self)
- override init() {
- do {
- libburrow.spawnInProcess(socketPath: try Constants.socketURL.path)
- } catch {
- logger.error("Failed to spawn: \(error)")
- }
- }
-
override func startTunnel(options: [String: NSObject]? = nil) async throws {
do {
+ libburrow.spawnInProcess(socketPath: try Constants.socketURL.path)
+
let client = try Client()
let command = BurrowRequest(id: 0, command: "ServerConfig")
@@ -37,7 +31,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
command: BurrowStartRequest(
Start: BurrowStartRequest.StartOptions(
tun: BurrowStartRequest.TunOptions(
- name: nil, no_pi: false, tun_excl: false, tun_retrieve: true, address: []
+ name: nil, no_pi: false, tun_excl: false, tun_retrieve: true, address: nil
)
)
)
@@ -50,34 +44,14 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
}
}
- override func stopTunnel(with reason: NEProviderStopReason) async {
- do {
- let client = try Client()
- let command = BurrowRequest(id: 0, command: "Stop")
- let data = try await client.request(command, type: Response>.self)
- self.logger.log("Stopped client.")
- } catch {
- self.logger.error("Failed to stop tunnel: \(error)")
- }
- }
-
private func generateTunSettings(from: ServerConfigData) -> NETunnelNetworkSettings? {
let cfig = from.ServerConfig
- let nst = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1")
- var v4Addresses = [String]()
- var v6Addresses = [String]()
- for addr in cfig.address {
- if IPv4Address(addr) != nil {
- v6Addresses.append(addr)
- }
- if IPv6Address(addr) != nil {
- v4Addresses.append(addr)
- }
+ guard let addr = cfig.address else {
+ return nil
}
- nst.ipv4Settings = NEIPv4Settings(addresses: v4Addresses, subnetMasks: v4Addresses.map { _ in
- "255.255.255.0"
- })
- nst.ipv6Settings = NEIPv6Settings(addresses: v6Addresses, networkPrefixLengths: v6Addresses.map { _ in 64 })
+ // Using a makeshift remote tunnel address
+ let nst = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1")
+ nst.ipv4Settings = NEIPv4Settings(addresses: [addr], subnetMasks: ["255.255.255.0"])
logger.log("Initialized ipv4 settings: \(nst.ipv4Settings)")
return nst
}
diff --git a/Apple/NetworkExtension/libburrow/build-rust.sh b/Apple/NetworkExtension/libburrow/build-rust.sh
index fffa0d0..1ac73fb 100755
--- a/Apple/NetworkExtension/libburrow/build-rust.sh
+++ b/Apple/NetworkExtension/libburrow/build-rust.sh
@@ -56,10 +56,10 @@ CARGO_ARGS+=("--lib")
# Pass the configuration (Debug or Release) through to cargo
if [[ $SWIFT_ACTIVE_COMPILATION_CONDITIONS == *DEBUG* ]]; then
- CARGO_TARGET_SUBDIR="debug"
+ CARGO_DIR="debug"
else
CARGO_ARGS+=("--release")
- CARGO_TARGET_SUBDIR="release"
+ CARGO_DIR="release"
fi
if [[ -x "$(command -v rustup)" ]]; then
@@ -70,11 +70,11 @@ fi
# Run cargo without the various environment variables set by Xcode.
# Those variables can confuse cargo and the build scripts it runs.
-env -i PATH="$CARGO_PATH" CARGO_TARGET_DIR="${CONFIGURATION_TEMP_DIR}/target" cargo build "${CARGO_ARGS[@]}"
+env -i PATH="$CARGO_PATH" cargo build "${CARGO_ARGS[@]}"
mkdir -p "${BUILT_PRODUCTS_DIR}"
# Use `lipo` to merge the architectures together into BUILT_PRODUCTS_DIR
/usr/bin/xcrun --sdk $PLATFORM_NAME lipo \
- -create $(printf "${CONFIGURATION_TEMP_DIR}/target/%q/${CARGO_TARGET_SUBDIR}/libburrow.a " "${RUST_TARGETS[@]}") \
+ -create $(printf "${PROJECT_DIR}/../target/%q/${CARGO_DIR}/libburrow.a " "${RUST_TARGETS[@]}") \
-output "${BUILT_PRODUCTS_DIR}/libburrow.a"
diff --git a/Apple/Shared/Constants.swift b/Apple/Shared/Constants.swift
index 634c500..cb56cb3 100644
--- a/Apple/Shared/Constants.swift
+++ b/Apple/Shared/Constants.swift
@@ -7,7 +7,6 @@ public enum Constants {
public static let bundleIdentifier = AppBundleIdentifier
public static let appGroupIdentifier = AppGroupIdentifier
- public static let networkExtensionBundleIdentifier = NetworkExtensionBundleIdentifier
public static var groupContainerURL: URL {
get throws { try _groupContainerURL.get() }
diff --git a/Apple/Shared/Constants/Constants.h b/Apple/Shared/Constants/Constants.h
index 5278b61..09806c5 100644
--- a/Apple/Shared/Constants/Constants.h
+++ b/Apple/Shared/Constants/Constants.h
@@ -7,6 +7,5 @@ NS_ASSUME_NONNULL_BEGIN
static NSString * const AppBundleIdentifier = MACRO_STRING(APP_BUNDLE_IDENTIFIER);
static NSString * const AppGroupIdentifier = MACRO_STRING(APP_GROUP_IDENTIFIER);
-static NSString * const NetworkExtensionBundleIdentifier = MACRO_STRING(NETWORK_EXTENSION_BUNDLE_IDENTIFIER);
NS_ASSUME_NONNULL_END
diff --git a/Apple/Shared/Shared.xcconfig b/Apple/Shared/Shared.xcconfig
index f344e8b..50718bd 100644
--- a/Apple/Shared/Shared.xcconfig
+++ b/Apple/Shared/Shared.xcconfig
@@ -2,4 +2,4 @@ PRODUCT_NAME = BurrowShared
MERGEABLE_LIBRARY = YES
SWIFT_INCLUDE_PATHS = $(PROJECT_DIR)/Shared/Constants
-GCC_PREPROCESSOR_DEFINITIONS = APP_BUNDLE_IDENTIFIER=$(APP_BUNDLE_IDENTIFIER) APP_GROUP_IDENTIFIER=$(APP_GROUP_IDENTIFIER) NETWORK_EXTENSION_BUNDLE_IDENTIFIER=$(NETWORK_EXTENSION_BUNDLE_IDENTIFIER)
+GCC_PREPROCESSOR_DEFINITIONS = APP_BUNDLE_IDENTIFIER=$(APP_BUNDLE_IDENTIFIER) APP_GROUP_IDENTIFIER=$(APP_GROUP_IDENTIFIER)
diff --git a/Cargo.lock b/Cargo.lock
index a75bd28..85f11e7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1074,7 +1074,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
- "socket2",
+ "socket2 0.5.5",
"tokio",
"tower-service",
"tracing",
@@ -2114,6 +2114,16 @@ version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+[[package]]
+name = "socket2"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
[[package]]
name = "socket2"
version = "0.5.5"
@@ -2295,7 +2305,7 @@ dependencies = [
"mio",
"num_cpus",
"pin-project-lite",
- "socket2",
+ "socket2 0.5.5",
"tokio-macros",
"tracing",
"windows-sys 0.48.0",
@@ -2537,7 +2547,7 @@ dependencies = [
"reqwest",
"schemars",
"serde",
- "socket2",
+ "socket2 0.4.10",
"ssri",
"tempfile",
"tokio",
diff --git a/Dockerfile b/Dockerfile
index 9f54478..b1500bb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM docker.io/library/rust:1.76.0-slim-bookworm AS builder
+FROM docker.io/library/rust:1.70.0-slim-bookworm AS builder
ARG TARGETPLATFORM
ARG LLVM_VERSION=16
diff --git a/Makefile b/Makefile
index d0c9bd9..18b4b27 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-tun := $(shell ifconfig -l | sed 's/ /\n/g' | grep utun | tail -n 1)
+tun_num := $(shell ifconfig | awk -F 'utun|[: ]' '/utun[0-9]/ {print $$2}' | tail -n 1)
cargo_console := RUST_BACKTRACE=1 RUST_LOG=debug RUSTFLAGS='--cfg tokio_unstable' cargo run --all-features
cargo_norm := RUST_BACKTRACE=1 RUST_LOG=debug cargo run
@@ -17,33 +17,17 @@ daemon:
start:
@$(cargo_norm) start
-stop:
- @$(cargo_norm) stop
-
test-dns:
@sudo route delete 8.8.8.8
- @sudo route add 8.8.8.8 -interface $(tun)
+ @sudo route add 8.8.8.8 -interface utun$(tun_num)
@dig @8.8.8.8 hackclub.com
test-https:
@sudo route delete 193.183.0.162
- @sudo route add 193.183.0.162 -interface $(tun)
+ @sudo route add 193.183.0.162 -interface utun$(tun_num)
@curl -vv https://search.marginalia.nu
-v4_target := 146.190.62.39
test-http:
- @sudo route delete ${v4_target}
- @sudo route add ${v4_target} -interface $(tun)
- @curl -vv ${v4_target}:80
-
-test-ipv4:
- @sudo route delete ${v4_target}
- @sudo route add ${v4_target} -interface $(tun)
- @ping ${v4_target}
-
-v6_target := 2001:4860:4860::8888
-test-ipv6:
- @sudo route delete ${v6_target}
- @sudo route -n add -inet6 ${v6_target} -interface $(tun)
- @echo preparing
- @sudo ping6 -v ${v6_target}
+ @sudo route delete 146.190.62.39
+ @sudo route add 146.190.62.39 -interface utun$(tun_num)
+ @curl -vv 146.190.62.39:80
diff --git a/README.md b/README.md
index 89914d0..7492039 100644
--- a/README.md
+++ b/README.md
@@ -8,14 +8,13 @@ Burrow is an open source tool for burrowing through firewalls, built by teenager
## Contributing
-Burrow is fully open source, you can fork the repo and start contributing easily. For more information and in-depth discussions, visit the `#burrow` channel on the [Hack Club Slack](https://hackclub.com/slack/), here you can ask for help and talk with other people interested in burrow! Checkout [GETTING_STARTED.md](./docs/GETTING_STARTED.md) for build instructions and [GTK_APP.md](./docs/GTK_APP.md) for the Linux app.
+Burrow is fully open source, you can fork the repo and start contributing easily. For more information and in-depth discussions, visit the `#burrow` channel on the [Hack Club Slack](https://hackclub.com/slack/), here you can ask for help and talk with other people interested in burrow! For more information on how to contribute, please see [CONTRIBUTING.md]
The project structure is divided in the following folders:
```
Apple/ # Xcode project for burrow on macOS and iOS
burrow/ # Higher-level API library for tun and tun-async
-burrow-gtk/ # GTK project for burrow on Linux
tun/ # Low-level interface to OS networking
src/
tokio/ # Async/Tokio code
diff --git a/burrow-gtk/Cargo.lock b/burrow-gtk/Cargo.lock
index 6721318..d0b7009 100644
--- a/burrow-gtk/Cargo.lock
+++ b/burrow-gtk/Cargo.lock
@@ -257,16 +257,16 @@ dependencies = [
"caps",
"chacha20poly1305",
"clap",
- "console",
+ "env_logger",
"fehler",
"futures",
"hmac",
"ip_network",
"ip_network_table",
+ "ipnet",
"libsystemd",
"log",
- "nix 0.27.1",
- "once_cell",
+ "nix",
"parking_lot",
"rand",
"rand_core",
@@ -281,6 +281,7 @@ dependencies = [
"tracing-oslog",
"tracing-subscriber",
"tun",
+ "uuid",
"x25519-dalek",
]
@@ -331,11 +332,11 @@ dependencies = [
[[package]]
name = "cairo-rs"
-version = "0.17.10"
+version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a"
+checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.2",
"cairo-sys-rs",
"glib",
"libc",
@@ -345,9 +346,9 @@ dependencies = [
[[package]]
name = "cairo-sys-rs"
-version = "0.17.10"
+version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1"
+checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51"
dependencies = [
"glib-sys",
"libc",
@@ -500,19 +501,6 @@ dependencies = [
"crossbeam-utils",
]
-[[package]]
-name = "console"
-version = "0.15.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
-dependencies = [
- "encode_unicode",
- "lazy_static",
- "libc",
- "unicode-width",
- "windows-sys 0.52.0",
-]
-
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@@ -629,12 +617,6 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
-[[package]]
-name = "encode_unicode"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
-
[[package]]
name = "encoding_rs"
version = "0.8.33"
@@ -644,6 +626,19 @@ dependencies = [
"cfg-if",
]
+[[package]]
+name = "env_logger"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
+dependencies = [
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
+]
+
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -735,14 +730,13 @@ dependencies = [
[[package]]
name = "flume"
-version = "0.10.14"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
+checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"futures-core",
"futures-sink",
"nanorand",
- "pin-project",
"spin",
]
@@ -873,11 +867,10 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
-version = "0.17.10"
+version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717"
+checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec"
dependencies = [
- "bitflags 1.3.2",
"gdk-pixbuf-sys",
"gio",
"glib",
@@ -887,9 +880,9 @@ dependencies = [
[[package]]
name = "gdk-pixbuf-sys"
-version = "0.17.10"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb"
+checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
dependencies = [
"gio-sys",
"glib-sys",
@@ -900,11 +893,10 @@ dependencies = [
[[package]]
name = "gdk4"
-version = "0.6.3"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff"
+checksum = "7edb019ad581f8ecf8ea8e4baa6df7c483a95b5a59be3140be6a9c3b0c632af6"
dependencies = [
- "bitflags 1.3.2",
"cairo-rs",
"gdk-pixbuf",
"gdk4-sys",
@@ -916,9 +908,9 @@ dependencies = [
[[package]]
name = "gdk4-sys"
-version = "0.6.3"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64"
+checksum = "dbab43f332a3cf1df9974da690b5bb0e26720ed09a228178ce52175372dcfef0"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -982,11 +974,10 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "gio"
-version = "0.17.10"
+version = "0.18.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a"
+checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73"
dependencies = [
- "bitflags 1.3.2",
"futures-channel",
"futures-core",
"futures-io",
@@ -1002,9 +993,9 @@ dependencies = [
[[package]]
name = "gio-sys"
-version = "0.17.10"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3"
+checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
dependencies = [
"glib-sys",
"gobject-sys",
@@ -1015,11 +1006,11 @@ dependencies = [
[[package]]
name = "glib"
-version = "0.17.10"
+version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b"
+checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.2",
"futures-channel",
"futures-core",
"futures-executor",
@@ -1044,24 +1035,23 @@ checksum = "3431c56f463443cba9bc3600248bc6d680cb614c2ee1cdd39dab5415bd12ac5c"
[[package]]
name = "glib-macros"
-version = "0.17.10"
+version = "0.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26"
+checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
dependencies = [
- "anyhow",
"heck",
- "proc-macro-crate",
+ "proc-macro-crate 2.0.1",
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.48",
]
[[package]]
name = "glib-sys"
-version = "0.17.10"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0"
+checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
dependencies = [
"libc",
"system-deps",
@@ -1075,9 +1065,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gobject-sys"
-version = "0.17.10"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062"
+checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
dependencies = [
"glib-sys",
"libc",
@@ -1086,9 +1076,9 @@ dependencies = [
[[package]]
name = "graphene-rs"
-version = "0.17.10"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9"
+checksum = "3b2228cda1505613a7a956cca69076892cfbda84fc2b7a62b94a41a272c0c401"
dependencies = [
"glib",
"graphene-sys",
@@ -1097,9 +1087,9 @@ dependencies = [
[[package]]
name = "graphene-sys"
-version = "0.17.10"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d"
+checksum = "cc4144cee8fc8788f2a9b73dc5f1d4e1189d1f95305c4cb7bd9c1af1cfa31f59"
dependencies = [
"glib-sys",
"libc",
@@ -1109,11 +1099,10 @@ dependencies = [
[[package]]
name = "gsk4"
-version = "0.6.3"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c"
+checksum = "0d958e351d2f210309b32d081c832d7de0aca0b077aa10d88336c6379bd01f7e"
dependencies = [
- "bitflags 1.3.2",
"cairo-rs",
"gdk4",
"glib",
@@ -1125,9 +1114,9 @@ dependencies = [
[[package]]
name = "gsk4-sys"
-version = "0.6.3"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0"
+checksum = "12bd9e3effea989f020e8f1ff3fa3b8c63ba93d43b899c11a118868853a56d55"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
@@ -1141,11 +1130,10 @@ dependencies = [
[[package]]
name = "gtk4"
-version = "0.6.6"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b"
+checksum = "5aeb51aa3e9728575a053e1f43543cd9992ac2477e1b186ad824fd4adfb70842"
dependencies = [
- "bitflags 1.3.2",
"cairo-rs",
"field-offset",
"futures-channel",
@@ -1158,18 +1146,17 @@ dependencies = [
"gtk4-macros",
"gtk4-sys",
"libc",
- "once_cell",
"pango",
]
[[package]]
name = "gtk4-macros"
-version = "0.6.6"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f"
+checksum = "d57ec49cf9b657f69a05bca8027cff0a8dfd0c49e812be026fc7311f2163832f"
dependencies = [
"anyhow",
- "proc-macro-crate",
+ "proc-macro-crate 1.3.1",
"proc-macro-error",
"proc-macro2",
"quote",
@@ -1178,9 +1165,9 @@ dependencies = [
[[package]]
name = "gtk4-sys"
-version = "0.6.3"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f"
+checksum = "54d8c4aa23638ce9faa2caf7e2a27d4a1295af2155c8e8d28c4d4eeca7a65eb8"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -1290,6 +1277,12 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
[[package]]
name = "hyper"
version = "0.14.28"
@@ -1383,6 +1376,20 @@ name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys 0.52.0",
+]
[[package]]
name = "itoa"
@@ -1422,11 +1429,10 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libadwaita"
-version = "0.4.4"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf"
+checksum = "2fe7e70c06507ed10a16cda707f358fbe60fe0dc237498f78c686ade92fd979c"
dependencies = [
- "bitflags 1.3.2",
"gdk-pixbuf",
"gdk4",
"gio",
@@ -1439,9 +1445,9 @@ dependencies = [
[[package]]
name = "libadwaita-sys"
-version = "0.4.4"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404"
+checksum = "5e10aaa38de1d53374f90deeb4535209adc40cc5dba37f9704724169bceec69a"
dependencies = [
"gdk4-sys",
"gio-sys",
@@ -1481,14 +1487,14 @@ dependencies = [
[[package]]
name = "libsystemd"
-version = "0.7.0"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c592dc396b464005f78a5853555b9f240bc5378bf5221acc4e129910b2678869"
+checksum = "88b9597a67aa1c81a6624603e6bd0bcefb9e0f94c9c54970ec53771082104b4e"
dependencies = [
"hmac",
"libc",
"log",
- "nix 0.27.1",
+ "nix",
"nom",
"once_cell",
"serde",
@@ -1669,18 +1675,6 @@ dependencies = [
"pin-utils",
]
-[[package]]
-name = "nix"
-version = "0.27.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
-dependencies = [
- "bitflags 2.4.2",
- "cfg-if",
- "libc",
- "memoffset 0.9.0",
-]
-
[[package]]
name = "nom"
version = "7.1.3"
@@ -1813,11 +1807,10 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pango"
-version = "0.17.10"
+version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48"
+checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
dependencies = [
- "bitflags 1.3.2",
"gio",
"glib",
"libc",
@@ -1827,9 +1820,9 @@ dependencies = [
[[package]]
name = "pango-sys"
-version = "0.17.10"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195"
+checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
dependencies = [
"glib-sys",
"gobject-sys",
@@ -1901,26 +1894,6 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
-[[package]]
-name = "pin-project"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.48",
-]
-
[[package]]
name = "pin-project-lite"
version = "0.2.13"
@@ -1988,6 +1961,16 @@ dependencies = [
"toml_edit 0.19.15",
]
+[[package]]
+name = "proc-macro-crate"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a"
+dependencies = [
+ "toml_datetime",
+ "toml_edit 0.20.2",
+]
+
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@@ -2115,9 +2098,8 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "relm4"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81"
+version = "0.7.0-beta.2"
+source = "git+https://github.com/Relm4/Relm4#e189eee06b887470e0fd65cbaf6d7c0161bed5ea"
dependencies = [
"async-trait",
"flume",
@@ -2133,9 +2115,8 @@ dependencies = [
[[package]]
name = "relm4-macros"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735"
+version = "0.7.0-beta.2"
+source = "git+https://github.com/Relm4/Relm4#e189eee06b887470e0fd65cbaf6d7c0161bed5ea"
dependencies = [
"proc-macro2",
"quote",
@@ -2566,6 +2547,15 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "thiserror"
version = "1.0.56"
@@ -2643,7 +2633,6 @@ dependencies = [
"pin-project-lite",
"socket2 0.5.5",
"tokio-macros",
- "tracing",
"windows-sys 0.48.0",
]
@@ -2850,7 +2839,7 @@ dependencies = [
"libc",
"libloading 0.7.4",
"log",
- "nix 0.26.4",
+ "nix",
"reqwest",
"schemars",
"serde",
@@ -2936,6 +2925,7 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
+ "getrandom",
"serde",
]
@@ -3088,6 +3078,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+[[package]]
+name = "winapi-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
diff --git a/burrow-gtk/Cargo.toml b/burrow-gtk/Cargo.toml
index 21cb52e..244c161 100644
--- a/burrow-gtk/Cargo.toml
+++ b/burrow-gtk/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0"
-relm4 = { version = "0.6", features = ["libadwaita", "gnome_44"]}
+relm4 = { features = ["libadwaita", "gnome_45"], git = "https://github.com/Relm4/Relm4" }
burrow = { version = "*", path = "../burrow/" }
tokio = { version = "1.35.0", features = ["time", "sync"] }
gettext-rs = { version = "0.7.0", features = ["gettext-system"] }
diff --git a/burrow-gtk/build-aux/Dockerfile b/burrow-gtk/build-aux/Dockerfile
deleted file mode 100644
index df07c4a..0000000
--- a/burrow-gtk/build-aux/Dockerfile
+++ /dev/null
@@ -1,18 +0,0 @@
-FROM fedora:39
-
-ENV DEBIAN_FRONTEND=noninteractive
-
-RUN set -eux && \
- dnf update -y && \
- dnf install -y clang ninja-build cmake meson gtk4-devel glib2-devel libadwaita-devel desktop-file-utils libappstream-glib util-linux wget fuse fuse-libs file
-
-RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
-ENV PATH="/root/.cargo/bin:${PATH}"
-
-WORKDIR /app
-COPY . /app
-
-RUN cd /app/burrow-gtk/ && \
- ./build-aux/build_appimage.sh
-
-
diff --git a/burrow-gtk/build-aux/build_appimage.sh b/burrow-gtk/build-aux/build_appimage.sh
deleted file mode 100755
index cd58c17..0000000
--- a/burrow-gtk/build-aux/build_appimage.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-set -ex
-
-BURROW_GTK_ROOT="$(readlink -f $(dirname -- "$(readlink -f -- "$BASH_SOURCE")")/..)"
-BURROW_GTK_BUILD="$BURROW_GTK_ROOT/build-appimage"
-LINUXDEPLOY_VERSION="${LINUXDEPLOY_VERSION:-"1-alpha-20240109-1"}"
-BURROW_BUILD_TYPE="${BURROW_BUILD_TYPE:-"release"}"
-
-if [ "$BURROW_GTK_ROOT" != $(pwd) ]; then
- echo "Make sure to cd into burrow-gtk"
- exit 1
-fi
-
-ARCHITECTURE=$(lscpu | grep Architecture | awk '{print $2}')
-
-if [ "$ARCHITECTURE" == "x86_64" ]; then
- wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/$LINUXDEPLOY_VERSION/linuxdeploy-x86_64.AppImage" -o /dev/null -O /tmp/linuxdeploy
- chmod a+x /tmp/linuxdeploy
-elif [ "$ARCHITECTURE" == "aarch64" ]; then
- wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/$LINUXDEPLOY_VERSION/linuxdeploy-aarch64.AppImage" -o /dev/null -O /tmp/linuxdeploy
- chmod a+x /tmp/linuxdeploy
-fi
-
-meson setup $BURROW_GTK_BUILD --bindir bin --prefix /usr --buildtype $BURROW_BUILD_TYPE
-meson compile -C $BURROW_GTK_BUILD
-DESTDIR=AppDir meson install -C $BURROW_GTK_BUILD
-cargo b --$BURROW_BUILD_TYPE --manifest-path=../Cargo.toml
-/tmp/linuxdeploy --appimage-extract-and-run --appdir $BURROW_GTK_BUILD/AppDir -e $BURROW_GTK_BUILD/../../target/$BURROW_BUILD_TYPE/burrow --output appimage
-mv *.AppImage $BURROW_GTK_BUILD
diff --git a/burrow-gtk/meson.build b/burrow-gtk/meson.build
index 8c2d5c1..70d8403 100644
--- a/burrow-gtk/meson.build
+++ b/burrow-gtk/meson.build
@@ -34,8 +34,8 @@ i18n = import('i18n')
gnome = import('gnome')
# External Dependencies
-dependency('gtk4', version: '>= 4.0')
-dependency('libadwaita-1', version: '>= 1.2')
+dependency('gtk4', version: '>= 4.12')
+dependency('libadwaita-1', version: '>= 1.4')
glib_compile_resources = find_program('glib-compile-resources', required: true)
glib_compile_schemas = find_program('glib-compile-schemas', required: true)
diff --git a/burrow-gtk/src/components/app.rs b/burrow-gtk/src/components/app.rs
index 62c98c0..b42b718 100644
--- a/burrow-gtk/src/components/app.rs
+++ b/burrow-gtk/src/components/app.rs
@@ -6,7 +6,7 @@ const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5);
pub struct App {
daemon_client: Arc>>,
- settings_screen: Controller,
+ _settings_screen: Controller,
switch_screen: AsyncController,
}
@@ -81,35 +81,23 @@ impl AsyncComponent for App {
let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build();
view_switcher_bar.set_reveal(true);
- // When libadwaita 1.4 support becomes more avaliable, this approach is more appropriate
- //
- // let toolbar = adw::ToolbarView::new();
- // toolbar.add_top_bar(
- // &adw::HeaderBar::builder()
- // .title_widget(>k::Label::new(Some("Burrow")))
- // .build(),
- // );
- // toolbar.add_bottom_bar(&view_switcher_bar);
- // toolbar.set_content(Some(&view_stack));
- // root.set_content(Some(&toolbar));
-
- let content = gtk::Box::new(gtk::Orientation::Vertical, 0);
- content.append(
+ let toolbar = adw::ToolbarView::new();
+ toolbar.add_top_bar(
&adw::HeaderBar::builder()
.title_widget(>k::Label::new(Some("Burrow")))
.build(),
);
- content.append(&view_stack);
- content.append(&view_switcher_bar);
+ toolbar.add_bottom_bar(&view_switcher_bar);
+ toolbar.set_content(Some(&view_stack));
- root.set_content(Some(&content));
+ root.set_content(Some(&toolbar));
sender.input(AppMsg::PostInit);
let model = App {
daemon_client,
switch_screen,
- settings_screen,
+ _settings_screen: settings_screen,
};
AsyncComponentParts { model, widgets }
@@ -132,23 +120,14 @@ impl AsyncComponent for App {
disconnected_daemon_client = true;
self.switch_screen
.emit(switch_screen::SwitchScreenMsg::DaemonDisconnect);
- self.settings_screen
- .emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
}
}
if disconnected_daemon_client || daemon_client.is_none() {
- match DaemonClient::new().await {
- Ok(new_daemon_client) => {
- *daemon_client = Some(new_daemon_client);
- self.switch_screen
- .emit(switch_screen::SwitchScreenMsg::DaemonReconnect);
- self.settings_screen
- .emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
- }
- Err(_e) => {
- // TODO: Handle Error
- }
+ *daemon_client = DaemonClient::new().await.ok();
+ if daemon_client.is_some() {
+ self.switch_screen
+ .emit(switch_screen::SwitchScreenMsg::DaemonReconnect);
}
}
}
diff --git a/burrow-gtk/src/components/mod.rs b/burrow-gtk/src/components/mod.rs
index b134809..b1cc938 100644
--- a/burrow-gtk/src/components/mod.rs
+++ b/burrow-gtk/src/components/mod.rs
@@ -18,4 +18,3 @@ mod settings_screen;
mod switch_screen;
pub use app::*;
-pub use settings::{DaemonGroupMsg, DiagGroupMsg};
diff --git a/burrow-gtk/src/components/settings/daemon_group.rs b/burrow-gtk/src/components/settings/daemon_group.rs
deleted file mode 100644
index 3817ca6..0000000
--- a/burrow-gtk/src/components/settings/daemon_group.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use super::*;
-use std::process::Command;
-
-#[derive(Debug)]
-pub struct DaemonGroup {
- system_setup: SystemSetup,
- daemon_client: Arc>>,
- already_running: bool,
-}
-
-pub struct DaemonGroupInit {
- pub daemon_client: Arc>>,
- pub system_setup: SystemSetup,
-}
-
-#[derive(Debug)]
-pub enum DaemonGroupMsg {
- LaunchLocal,
- DaemonStateChange,
-}
-
-#[relm4::component(pub, async)]
-impl AsyncComponent for DaemonGroup {
- type Init = DaemonGroupInit;
- type Input = DaemonGroupMsg;
- type Output = ();
- type CommandOutput = ();
-
- view! {
- #[name(group)]
- adw::PreferencesGroup {
- #[watch]
- set_sensitive:
- (model.system_setup == SystemSetup::AppImage || model.system_setup == SystemSetup::Other) &&
- !model.already_running,
- set_title: "Local Daemon",
- set_description: Some("Run Local Daemon"),
-
- gtk::Button {
- set_label: "Launch",
- connect_clicked => DaemonGroupMsg::LaunchLocal
- }
- }
- }
-
- async fn init(
- init: Self::Init,
- root: Self::Root,
- sender: AsyncComponentSender,
- ) -> AsyncComponentParts {
- // Should be impossible to panic here
- let model = DaemonGroup {
- system_setup: init.system_setup,
- daemon_client: init.daemon_client.clone(),
- already_running: init.daemon_client.lock().await.is_some(),
- };
-
- let widgets = view_output!();
-
- AsyncComponentParts { model, widgets }
- }
-
- async fn update(
- &mut self,
- msg: Self::Input,
- _sender: AsyncComponentSender,
- _root: &Self::Root,
- ) {
- match msg {
- DaemonGroupMsg::LaunchLocal => {
- let burrow_original_bin = std::env::vars()
- .find(|(k, _)| k == "APPDIR")
- .map(|(_, v)| v + "/usr/bin/burrow")
- .unwrap_or("/usr/bin/burrow".to_owned());
-
- let mut burrow_bin =
- String::from_utf8(Command::new("mktemp").output().unwrap().stdout).unwrap();
- burrow_bin.pop();
-
- let privileged_spawn_script = format!(
- r#"TEMP=$(mktemp -p /root)
-cp {} $TEMP
-chmod +x $TEMP
-setcap CAP_NET_BIND_SERVICE,CAP_NET_ADMIN+eip $TEMP
-mv $TEMP /tmp/burrow-detached-daemon"#,
- burrow_original_bin
- )
- .replace('\n', "&&");
-
- // TODO: Handle error condition
-
- Command::new("pkexec")
- .arg("sh")
- .arg("-c")
- .arg(privileged_spawn_script)
- .arg(&burrow_bin)
- .output()
- .unwrap();
-
- Command::new("/tmp/burrow-detached-daemon")
- .env("RUST_LOG", "debug")
- .arg("daemon")
- .spawn()
- .unwrap();
- }
- DaemonGroupMsg::DaemonStateChange => {
- self.already_running = self.daemon_client.lock().await.is_some();
- }
- }
- }
-}
diff --git a/burrow-gtk/src/components/settings/diag_group.rs b/burrow-gtk/src/components/settings/diag_group.rs
index a15e0ea..be542cd 100644
--- a/burrow-gtk/src/components/settings/diag_group.rs
+++ b/burrow-gtk/src/components/settings/diag_group.rs
@@ -1,10 +1,11 @@
use super::*;
+use diag::{StatusTernary, SystemSetup};
#[derive(Debug)]
pub struct DiagGroup {
daemon_client: Arc>>,
- system_setup: SystemSetup,
+ init_system: SystemSetup,
service_installed: StatusTernary,
socket_installed: StatusTernary,
socket_enabled: StatusTernary,
@@ -13,20 +14,19 @@ pub struct DiagGroup {
pub struct DiagGroupInit {
pub daemon_client: Arc>>,
- pub system_setup: SystemSetup,
}
impl DiagGroup {
async fn new(daemon_client: Arc>>) -> Result {
- let system_setup = SystemSetup::new();
+ let setup = SystemSetup::new();
let daemon_running = daemon_client.lock().await.is_some();
Ok(Self {
- service_installed: system_setup.is_service_installed()?,
- socket_installed: system_setup.is_socket_installed()?,
- socket_enabled: system_setup.is_socket_enabled()?,
+ service_installed: setup.is_service_installed()?,
+ socket_installed: setup.is_socket_installed()?,
+ socket_enabled: setup.is_socket_enabled()?,
daemon_running,
- system_setup,
+ init_system: setup,
daemon_client,
})
}
@@ -52,7 +52,7 @@ impl AsyncComponent for DiagGroup {
adw::ActionRow {
#[watch]
- set_title: &format!("System Type: {}", model.system_setup)
+ set_title: &format!("Init System: {}", model.init_system)
},
adw::ActionRow {
#[watch]
diff --git a/burrow-gtk/src/components/settings/mod.rs b/burrow-gtk/src/components/settings/mod.rs
index aa87db2..53f46d4 100644
--- a/burrow-gtk/src/components/settings/mod.rs
+++ b/burrow-gtk/src/components/settings/mod.rs
@@ -1,8 +1,5 @@
use super::*;
-use diag::{StatusTernary, SystemSetup};
-mod daemon_group;
mod diag_group;
-pub use daemon_group::{DaemonGroup, DaemonGroupInit, DaemonGroupMsg};
-pub use diag_group::{DiagGroup, DiagGroupInit, DiagGroupMsg};
+pub use diag_group::{DiagGroup, DiagGroupInit};
diff --git a/burrow-gtk/src/components/settings_screen.rs b/burrow-gtk/src/components/settings_screen.rs
index 971f262..778eb84 100644
--- a/burrow-gtk/src/components/settings_screen.rs
+++ b/burrow-gtk/src/components/settings_screen.rs
@@ -1,24 +1,17 @@
use super::*;
-use diag::SystemSetup;
pub struct SettingsScreen {
- diag_group: AsyncController,
- daemon_group: AsyncController,
+ _diag_group: AsyncController,
}
pub struct SettingsScreenInit {
pub daemon_client: Arc>>,
}
-#[derive(Debug, PartialEq, Eq)]
-pub enum SettingsScreenMsg {
- DaemonStateChange,
-}
-
#[relm4::component(pub)]
impl SimpleComponent for SettingsScreen {
type Init = SettingsScreenInit;
- type Input = SettingsScreenMsg;
+ type Input = ();
type Output = ();
view! {
@@ -28,44 +21,24 @@ impl SimpleComponent for SettingsScreen {
fn init(
init: Self::Init,
- root: &Self::Root,
+ root: Self::Root,
sender: ComponentSender,
) -> ComponentParts {
- let system_setup = SystemSetup::new();
-
let diag_group = settings::DiagGroup::builder()
.launch(settings::DiagGroupInit {
- system_setup,
daemon_client: Arc::clone(&init.daemon_client),
})
- .forward(sender.input_sender(), |_| {
- SettingsScreenMsg::DaemonStateChange
- });
-
- let daemon_group = settings::DaemonGroup::builder()
- .launch(settings::DaemonGroupInit {
- system_setup,
- daemon_client: Arc::clone(&init.daemon_client),
- })
- .forward(sender.input_sender(), |_| {
- SettingsScreenMsg::DaemonStateChange
- });
+ .forward(sender.input_sender(), |_| ());
let widgets = view_output!();
widgets.preferences.add(diag_group.widget());
- widgets.preferences.add(daemon_group.widget());
- let model = SettingsScreen { diag_group, daemon_group };
+ let model = SettingsScreen {
+ _diag_group: diag_group,
+ };
ComponentParts { model, widgets }
}
- fn update(&mut self, _: Self::Input, _sender: ComponentSender) {
- // Currently, `SettingsScreenMsg` only has one variant, so the if is ambiguous.
- //
- // if let SettingsScreenMsg::DaemonStateChange = msg {
- self.diag_group.emit(DiagGroupMsg::Refresh);
- self.daemon_group.emit(DaemonGroupMsg::DaemonStateChange);
- // }
- }
+ fn update(&mut self, _: Self::Input, _sender: ComponentSender) {}
}
diff --git a/burrow-gtk/src/components/switch_screen.rs b/burrow-gtk/src/components/switch_screen.rs
index f660536..a296c09 100644
--- a/burrow-gtk/src/components/switch_screen.rs
+++ b/burrow-gtk/src/components/switch_screen.rs
@@ -29,7 +29,7 @@ impl AsyncComponent for SwitchScreen {
view! {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
- set_valign: Align::Fill,
+ set_valign: Align::BaselineFill,
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
diff --git a/burrow-gtk/src/diag.rs b/burrow-gtk/src/diag.rs
index ab4757e..348293e 100644
--- a/burrow-gtk/src/diag.rs
+++ b/burrow-gtk/src/diag.rs
@@ -15,18 +15,15 @@ pub enum StatusTernary {
// Realistically, we may not explicitly "support" non-systemd platforms which would simply this
// code greatly.
// Along with replacing [`StatusTernary`] with good old [`bool`].
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy)]
pub enum SystemSetup {
Systemd,
- AppImage,
Other,
}
impl SystemSetup {
pub fn new() -> Self {
- if is_appimage() {
- SystemSetup::AppImage
- } else if Command::new("systemctl").arg("--version").output().is_ok() {
+ if Command::new("systemctl").arg("--version").output().is_ok() {
SystemSetup::Systemd
} else {
SystemSetup::Other
@@ -36,7 +33,6 @@ impl SystemSetup {
pub fn is_service_installed(&self) -> Result {
match self {
SystemSetup::Systemd => Ok(fs::metadata(SYSTEMD_SERVICE_LOC).is_ok().into()),
- SystemSetup::AppImage => Ok(StatusTernary::NA),
SystemSetup::Other => Ok(StatusTernary::NA),
}
}
@@ -44,7 +40,6 @@ impl SystemSetup {
pub fn is_socket_installed(&self) -> Result {
match self {
SystemSetup::Systemd => Ok(fs::metadata(SYSTEMD_SOCKET_LOC).is_ok().into()),
- SystemSetup::AppImage => Ok(StatusTernary::NA),
SystemSetup::Other => Ok(StatusTernary::NA),
}
}
@@ -60,7 +55,6 @@ impl SystemSetup {
let output = String::from_utf8(output)?;
Ok((output == "enabled\n").into())
}
- SystemSetup::AppImage => Ok(StatusTernary::NA),
SystemSetup::Other => Ok(StatusTernary::NA),
}
}
@@ -80,12 +74,7 @@ impl Display for SystemSetup {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
SystemSetup::Systemd => "Systemd",
- SystemSetup::AppImage => "AppImage",
SystemSetup::Other => "Other",
})
}
}
-
-pub fn is_appimage() -> bool {
- std::env::vars().any(|(k, _)| k == "APPDIR")
-}
diff --git a/burrow-server-compose.yml b/burrow-server-compose.yml
deleted file mode 100644
index 4ba31ee..0000000
--- a/burrow-server-compose.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-version: "2.1"
-networks:
- wg6:
- enable_ipv6: true
- ipam:
- driver: default
- config:
- - subnet: "aa:bb:cc:de::/64"
-services:
- burrow:
- image: lscr.io/linuxserver/wireguard:latest
- privileged: true
- container_name: burrow_server
- cap_add:
- - NET_ADMIN
- - SYS_MODULE
- environment:
- - PUID=1000
- - PGID=1000
- - TZ=Asia/Calcutta
- - SERVERURL=wg.burrow.rs
- - SERVERPORT=51820
- - PEERS=10
- - PEERDNS=1.1.1.1
- - INTERNAL_SUBNET=10.13.13.0
- - ALLOWEDIPS=0.0.0.0/0, ::/0
- - PERSISTENTKEEPALIVE_PEERS=all
- - LOG_CONFS=true #optional
- volumes:
- - ./config:/config
- - /lib/modules:/lib/modules
- ports:
- - 51820:51820/udp
- sysctls:
- - net.ipv4.conf.all.src_valid_mark=1
- - net.ipv6.conf.all.disable_ipv6=0
- - net.ipv6.conf.eth0.proxy_ndp=1
- restart: unless-stopped
\ No newline at end of file
diff --git a/burrow/src/daemon/instance.rs b/burrow/src/daemon/instance.rs
index 0d3e726..34e9878 100644
--- a/burrow/src/daemon/instance.rs
+++ b/burrow/src/daemon/instance.rs
@@ -21,7 +21,7 @@ enum RunState {
pub struct DaemonInstance {
rx: async_channel::Receiver,
sx: async_channel::Sender,
- tun_interface: Arc>>,
+ tun_interface: Option>>,
wg_interface: Arc>,
wg_state: RunState,
}
@@ -36,7 +36,7 @@ impl DaemonInstance {
rx,
sx,
wg_interface,
- tun_interface: Arc::new(RwLock::new(None)),
+ tun_interface: None,
wg_state: RunState::Idle,
}
}
@@ -50,15 +50,15 @@ impl DaemonInstance {
warn!("Got start, but tun interface already up.");
}
RunState::Idle => {
- let tun_if = st.tun.open()?;
- debug!("Setting tun on wg_interface");
- self.wg_interface.read().await.set_tun(tun_if).await;
- debug!("tun set on wg_interface");
+ let tun_if = Arc::new(RwLock::new(st.tun.open()?));
debug!("Setting tun_interface");
- self.tun_interface = self.wg_interface.read().await.get_tun();
+ self.tun_interface = Some(tun_if.clone());
debug!("tun_interface set: {:?}", self.tun_interface);
+ debug!("Setting tun on wg_interface");
+ self.wg_interface.write().await.set_tun(tun_if);
+ debug!("tun set on wg_interface");
debug!("Cloning wg_interface");
let tmp_wg = self.wg_interface.clone();
@@ -82,18 +82,22 @@ impl DaemonInstance {
}
Ok(DaemonResponseData::None)
}
- DaemonCommand::ServerInfo => match &self.tun_interface.read().await.as_ref() {
+ DaemonCommand::ServerInfo => match &self.tun_interface {
None => Ok(DaemonResponseData::None),
Some(ti) => {
info!("{:?}", ti);
Ok(DaemonResponseData::ServerInfo(ServerInfo::try_from(
- ti.inner.get_ref(),
+ ti.read().await.inner.get_ref(),
)?))
}
},
DaemonCommand::Stop => {
- self.wg_interface.read().await.remove_tun().await;
- self.wg_state = RunState::Idle;
+ if self.tun_interface.is_some() {
+ self.tun_interface = None;
+ info!("Daemon stopping tun interface.");
+ } else {
+ warn!("Got stop, but tun interface is not up.")
+ }
Ok(DaemonResponseData::None)
}
DaemonCommand::ServerConfig => {
diff --git a/burrow/src/daemon/response.rs b/burrow/src/daemon/response.rs
index 37ee5d9..172d4c7 100644
--- a/burrow/src/daemon/response.rs
+++ b/burrow/src/daemon/response.rs
@@ -57,7 +57,7 @@ impl TryFrom<&TunInterface> for ServerInfo {
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct ServerConfig {
- pub address: Vec,
+ pub address: Option,
pub name: Option,
pub mtu: Option,
}
@@ -65,7 +65,7 @@ pub struct ServerConfig {
impl Default for ServerConfig {
fn default() -> Self {
Self {
- address: vec!["10.13.13.2".to_string()], // Dummy remote address
+ address: Some("10.13.13.2".to_string()), // Dummy remote address
name: None,
mtu: None,
}
diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap
index f78eeaa..0eb9096 100644
--- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap
+++ b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap
@@ -2,4 +2,4 @@
source: burrow/src/daemon/command.rs
expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions {\n tun: TunOptions { ..TunOptions::default() },\n })).unwrap()"
---
-{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}}
+{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":null}}}
diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap
index eee563d..bfd5117 100644
--- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap
+++ b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap
@@ -2,4 +2,4 @@
source: burrow/src/daemon/command.rs
expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions::default())).unwrap()"
---
-{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}}
+{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":null}}}
diff --git a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap
index 0b9385c..9752ebc 100644
--- a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap
+++ b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap
@@ -2,4 +2,4 @@
source: burrow/src/daemon/response.rs
expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::ServerConfig(ServerConfig::default()))))?"
---
-{"result":{"Ok":{"ServerConfig":{"address":["10.13.13.2"],"name":null,"mtu":null}}},"id":0}
+{"result":{"Ok":{"ServerConfig":{"address":"10.13.13.2","name":null,"mtu":null}}},"id":0}
diff --git a/burrow/src/main.rs b/burrow/src/main.rs
index 71d1c02..79bb70b 100644
--- a/burrow/src/main.rs
+++ b/burrow/src/main.rs
@@ -55,7 +55,7 @@ async fn try_start() -> Result<()> {
let mut client = DaemonClient::new().await?;
client
.send_command(DaemonCommand::Start(DaemonStartOptions {
- tun: TunOptions::new().address(vec!["10.13.13.2", "::2"]),
+ tun: TunOptions::new().address("10.13.13.2"),
}))
.await
.map(|_| ())
diff --git a/burrow/src/tracing.rs b/burrow/src/tracing.rs
index 861b41f..279f45d 100644
--- a/burrow/src/tracing.rs
+++ b/burrow/src/tracing.rs
@@ -39,7 +39,6 @@ pub fn initialize() {
tracing_subscriber::fmt::layer()
.with_level(true)
.with_writer(std::io::stderr)
- .with_line_number(true)
.compact()
.with_filter(EnvFilter::from_default_env())
});
diff --git a/burrow/src/wireguard/config.rs b/burrow/src/wireguard/config.rs
index ed7b3cd..afe7499 100644
--- a/burrow/src/wireguard/config.rs
+++ b/burrow/src/wireguard/config.rs
@@ -42,7 +42,7 @@ pub struct Peer {
pub struct Interface {
pub private_key: String,
- pub address: Vec,
+ pub address: String,
pub listen_port: u32,
pub dns: Vec,
pub mtu: Option,
@@ -93,8 +93,8 @@ impl Default for Config {
fn default() -> Self {
Self {
interface: Interface {
- private_key: "OEPVdomeLTxTIBvv3TYsJRge0Hp9NMiY0sIrhT8OWG8=".into(),
- address: vec!["10.13.13.2/24".into()],
+ private_key: "GNqIAOCRxjl/cicZyvkvpTklgQuUmGUIEkH7IXF/sEE=".into(),
+ address: "10.13.13.2/24".into(),
listen_port: 51820,
dns: Default::default(),
mtu: Default::default(),
@@ -102,8 +102,8 @@ impl Default for Config {
peers: vec![Peer {
endpoint: "wg.burrow.rs:51820".into(),
allowed_ips: vec!["8.8.8.8/32".into(), "0.0.0.0/0".into()],
- public_key: "8GaFjVO6c4luCHG4ONO+1bFG8tO+Zz5/Gy+Geht1USM=".into(),
- preshared_key: Some("ha7j4BjD49sIzyF9SNlbueK0AMHghlj6+u0G3bzC698=".into()),
+ public_key: "uy75leriJay0+oHLhRMpV+A5xAQ0hCJ+q7Ww81AOvT4=".into(),
+ preshared_key: Some("s7lx/mg+reVEMnGnqeyYOQkzD86n2+gYnx1M9ygi08k=".into()),
persistent_keepalive: Default::default(),
name: Default::default(),
}],
diff --git a/burrow/src/wireguard/iface.rs b/burrow/src/wireguard/iface.rs
index 6097082..620c96c 100755
--- a/burrow/src/wireguard/iface.rs
+++ b/burrow/src/wireguard/iface.rs
@@ -1,11 +1,10 @@
use std::{net::IpAddr, sync::Arc};
-use std::ops::Deref;
use anyhow::Error;
use fehler::throws;
use futures::future::join_all;
use ip_network_table::IpNetworkTable;
-use tokio::sync::{RwLock, Notify};
+use tokio::sync::RwLock;
use tracing::{debug, error};
use tun::tokio::TunInterface;
@@ -47,21 +46,9 @@ impl FromIterator for IndexedPcbs {
}
}
-enum IfaceStatus {
- Running,
- Idle
-}
-
pub struct Interface {
- tun: Arc>>,
+ tun: Option>>,
pcbs: Arc,
- status: Arc>,
- stop_notifier: Arc,
-}
-
-async fn is_running(status: Arc>) -> bool {
- let st = status.read().await;
- matches!(st.deref(), IfaceStatus::Running)
}
impl Interface {
@@ -73,54 +60,35 @@ impl Interface {
.collect::>()?;
let pcbs = Arc::new(pcbs);
- Self { pcbs, tun: Arc::new(RwLock::new(None)), status: Arc::new(RwLock::new(IfaceStatus::Idle)), stop_notifier: Arc::new(Notify::new()) }
+ Self { pcbs, tun: None }
}
- pub async fn set_tun(&self, tun: TunInterface) {
- debug!("Setting tun interface");
- self.tun.write().await.replace(tun);
- let mut st = self.status.write().await;
- *st = IfaceStatus::Running;
- }
-
- pub fn get_tun(&self) -> Arc>> {
- self.tun.clone()
- }
-
- pub async fn remove_tun(&self){
- let mut st = self.status.write().await;
- self.stop_notifier.notify_waiters();
- *st = IfaceStatus::Idle;
+ pub fn set_tun(&mut self, tun: Arc>) {
+ self.tun = Some(tun);
}
pub async fn run(&self) -> anyhow::Result<()> {
let pcbs = self.pcbs.clone();
let tun = self
.tun
- .clone();
- let status = self.status.clone();
- let stop_notifier = self.stop_notifier.clone();
+ .clone()
+ .ok_or(anyhow::anyhow!("tun interface does not exist"))?;
log::info!("Starting interface");
let outgoing = async move {
- while is_running(status.clone()).await {
+ loop {
let mut buf = [0u8; 3000];
let src = {
- let t = tun.read().await;
- let Some(_tun) = t.as_ref() else {
- continue;
+ let src = match tun.read().await.recv(&mut buf[..]).await {
+ Ok(len) => &buf[..len],
+ Err(e) => {
+ error!("Failed to read from interface: {}", e);
+ continue
+ }
};
- tokio::select! {
- _ = stop_notifier.notified() => continue,
- pkg = _tun.recv(&mut buf[..]) => match pkg {
- Ok(len) => &buf[..len],
- Err(e) => {
- error!("Failed to read from interface: {}", e);
- continue
- }
- },
- }
+ debug!("Read {} bytes from interface", src.len());
+ src
};
let dst_addr = match Tunnel::dst_address(src) {
@@ -155,7 +123,8 @@ impl Interface {
let mut tsks = vec![];
let tun = self
.tun
- .clone();
+ .clone()
+ .ok_or(anyhow::anyhow!("tun interface does not exist"))?;
let outgoing = tokio::task::spawn(outgoing);
tsks.push(outgoing);
debug!("preparing to spawn read tasks");
@@ -180,10 +149,9 @@ impl Interface {
};
let pcb = pcbs.pcbs[i].clone();
- let status = self.status.clone();
let update_timers_tsk = async move {
let mut buf = [0u8; 65535];
- while is_running(status.clone()).await {
+ loop {
tokio::time::sleep(tokio::time::Duration::from_millis(250)).await;
match pcb.update_timers(&mut buf).await {
Ok(..) => (),
@@ -196,9 +164,8 @@ impl Interface {
};
let pcb = pcbs.pcbs[i].clone();
- let status = self.status.clone();
let reset_rate_limiter_tsk = async move {
- while is_running(status.clone()).await {
+ loop {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
pcb.reset_rate_limiter().await;
}
diff --git a/burrow/src/wireguard/pcb.rs b/burrow/src/wireguard/pcb.rs
index 974d84e..db57968 100755
--- a/burrow/src/wireguard/pcb.rs
+++ b/burrow/src/wireguard/pcb.rs
@@ -54,7 +54,7 @@ impl PeerPcb {
Ok(())
}
- pub async fn run(&self, tun_interface: Arc>>) -> Result<(), Error> {
+ pub async fn run(&self, tun_interface: Arc>) -> Result<(), Error> {
tracing::debug!("starting read loop for pcb... for {:?}", &self);
let rid: i32 = random();
let mut buf: [u8; 3000] = [0u8; 3000];
@@ -106,12 +106,12 @@ impl PeerPcb {
}
TunnResult::WriteToTunnelV4(packet, addr) => {
tracing::debug!("WriteToTunnelV4: {:?}, {:?}", packet, addr);
- tun_interface.read().await.as_ref().ok_or(anyhow::anyhow!("tun interface does not exist"))?.send(packet).await?;
+ tun_interface.read().await.send(packet).await?;
break
}
TunnResult::WriteToTunnelV6(packet, addr) => {
tracing::debug!("WriteToTunnelV6: {:?}, {:?}", packet, addr);
- tun_interface.read().await.as_ref().ok_or(anyhow::anyhow!("tun interface does not exist"))?.send(packet).await?;
+ tun_interface.read().await.send(packet).await?;
break
}
}
diff --git a/docs/GTK_APP.md b/docs/GTK_APP.md
index ef73d2b..9b103a3 100644
--- a/docs/GTK_APP.md
+++ b/docs/GTK_APP.md
@@ -1,79 +1,22 @@
# Linux GTK App Getting Started
-Currently, the GTK App can be built as a binary or as an AppImage.
-Note that the flatpak version can compile but will not run properly!
-
## Dependencies
### Install Build Dependencies
-
- Debian
-
- > Note: Burrow currently cannot compile on Debian Stable (Bookworm) due to its outdated dependencies
-
- 1. Install build dependencies
-
- ```
- sudo apt install -y clang meson cmake pkg-config libgtk-4-dev libadwaita-1-dev gettext desktop-file-utils
- ```
-
- 2. Install flatpak builder (Optional)
-
- ```
- sudo apt install -y flatpak-builder
- ```
-
- 3. Install AppImage build tools (Optional)
-
- ```
- sudo apt install -y wget fuse file
- ```
-
-
-
Fedora
- 1. Install build dependencies
+ 1. Install build dependencies
```
- sudo dnf install -y clang ninja-build cmake meson gtk4-devel glib2-devel libadwaita-devel desktop-file-utils libappstream-glib
+ sudo dnf install clang ninja cmake meson gtk4-devel glib2-devel libadwaita-devel desktop-file-utils libappstream-glib
```
2. Install flatpak builder (Optional)
```
- sudo dnf install -y flatpak-builder
- ```
-
- 3. Install AppImage build tools (Optional)
-
- ```
- sudo dnf install -y util-linux wget fuse fuse-libs file
- ```
-
-
-
-
- Void Linux (glibc)
-
- 1. Install build dependencies
-
- ```
- sudo xbps-install -Sy gcc clang meson cmake pkg-config gtk4-devel gettext desktop-file-utils gtk4-update-icon-cache appstream-glib
- ```
-
- 2. Install flatpak builder (Optional)
-
- ```
- sudo xbps-install -Sy flatpak-builder
- ```
-
- 3. Install AppImage build tools (Optional)
-
- ```
- sudo xbps-install -Sy wget fuse file
+ sudo dnf install flatpak-builder
```
@@ -108,10 +51,10 @@ flatpak install --user \
Flatpak
- 1. Compile and install the flatpak
+ 1. Compile and install the flatpak
```
- flatpak-builder
+ flatpak-builder
--user --install --force-clean --disable-rofiles-fuse \
flatpak_debug/ \
burrow-gtk/build-aux/com.hackclub.burrow.devel.json
@@ -119,23 +62,6 @@ flatpak install --user \
-
- AppImage
-
- 1. Enter the `burrow-gtk`
-
- ```bash
- cd burrow-gtk
- ```
-
- 2. Compile the AppImage
-
- ```
- ./build-aux/build_appimage.sh
- ```
-
-
-
## Running
@@ -157,14 +83,3 @@ flatpak install --user \
```
-
-
- AppImage
-
- The compiled binary can be found in `build-appimage/Burrow-*.AppImage`.
-
- ```
- ./build-appimage/Burrow-*.AppImage
- ```
-
-
diff --git a/server_patch.txt b/server_patch.txt
deleted file mode 100644
index de8e14c..0000000
--- a/server_patch.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add this to ~/server/wg0.conf upon regeneration
-
-PostUp = iptables -A FORWARD -i %i -j ACCEPT
-
-PostUp = iptables -A FORWARD -o %i -j ACCEPT
-
-PostUp = iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
-
-PostUp = ip6tables -A FORWARD -i %i -j ACCEPT
-
-PostUp = ip6tables -A FORWARD -o %i -j ACCEPT
-
-PostDown = iptables -D FORWARD -i %i -j ACCEPT
-
-PostDown = iptables -D FORWARD -o %i -j ACCEPT
-
-PostDown = iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE
-
-PostDown = ip6tables -D FORWARD -i %i -j ACCEPT
-
-PostDown = ip6tables -D FORWARD -o %i -j ACCEPT
\ No newline at end of file
diff --git a/tun/Cargo.toml b/tun/Cargo.toml
index 7413f65..e67e45f 100644
--- a/tun/Cargo.toml
+++ b/tun/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
libc = "0.2"
fehler = "1.0"
nix = { version = "0.26", features = ["ioctl"] }
-socket2 = "0.5"
+socket2 = "0.4"
tokio = { version = "1.28", features = [] }
byteorder = "1.4"
tracing = "0.1"
diff --git a/tun/src/options.rs b/tun/src/options.rs
index e21bf5f..339f71a 100644
--- a/tun/src/options.rs
+++ b/tun/src/options.rs
@@ -21,7 +21,7 @@ pub struct TunOptions {
/// (Apple) Retrieve the tun interface
pub tun_retrieve: bool,
/// (Linux) The IP address of the tun interface.
- pub address: Vec,
+ pub address: Option,
}
impl TunOptions {
@@ -44,8 +44,8 @@ impl TunOptions {
self
}
- pub fn address(mut self, address: Vec) -> Self {
- self.address = address.iter().map(|x| x.to_string()).collect();
+ pub fn address(mut self, address: impl ToString) -> Self {
+ self.address = Some(address.to_string());
self
}
diff --git a/tun/src/unix/apple/kern_control.rs b/tun/src/unix/apple/kern_control.rs
index 6075233..76e576f 100644
--- a/tun/src/unix/apple/kern_control.rs
+++ b/tun/src/unix/apple/kern_control.rs
@@ -21,7 +21,7 @@ impl SysControlSocket for socket2::Socket {
unsafe { sys::resolve_ctl_info(self.as_raw_fd(), &mut info as *mut sys::ctl_info)? };
let (_, addr) = unsafe {
- socket2::SockAddr::try_init(|addr_storage, len| {
+ socket2::SockAddr::init(|addr_storage, len| {
*len = size_of::() as u32;
let addr: &mut sys::sockaddr_ctl = &mut *addr_storage.cast();
diff --git a/tun/src/unix/apple/mod.rs b/tun/src/unix/apple/mod.rs
index 6e859ca..2787cde 100644
--- a/tun/src/unix/apple/mod.rs
+++ b/tun/src/unix/apple/mod.rs
@@ -1,11 +1,13 @@
-use std::{io::{Error, IoSlice}, mem, net::{Ipv4Addr, SocketAddrV4}, os::fd::{AsRawFd, FromRawFd, RawFd}, ptr};
-use std::net::{IpAddr, Ipv6Addr, SocketAddrV6};
-use std::ptr::addr_of;
+use std::{
+ io::{Error, IoSlice},
+ mem,
+ net::{Ipv4Addr, SocketAddrV4},
+ os::fd::{AsRawFd, FromRawFd, RawFd},
+};
use byteorder::{ByteOrder, NetworkEndian};
use fehler::throws;
-use libc::{c_char, iovec, writev, AF_INET, AF_INET6, sockaddr_in6};
-use nix::sys::socket::SockaddrIn6;
+use libc::{c_char, iovec, writev, AF_INET, AF_INET6};
use socket2::{Domain, SockAddr, Socket, Type};
use tracing::{self, instrument};
@@ -47,7 +49,7 @@ impl TunInterface {
pub fn retrieve() -> Option {
(3..100)
.filter_map(|fd| unsafe {
- let peer_addr = socket2::SockAddr::try_init(|storage, len| {
+ let peer_addr = socket2::SockAddr::init(|storage, len| {
*len = mem::size_of::() as u32;
libc::getpeername(fd, storage as *mut _, len);
Ok(())
@@ -69,12 +71,9 @@ impl TunInterface {
#[throws]
fn configure(&self, options: TunOptions) {
- for addr in options.address{
- if let Ok(addr) = addr.parse::() {
- match addr {
- IpAddr::V4(addr) => {self.set_ipv4_addr(addr)?}
- IpAddr::V6(addr) => {self.set_ipv6_addr(addr)?}
- }
+ if let Some(addr) = options.address {
+ if let Ok(addr) = addr.parse() {
+ self.set_ipv4_addr(addr)?;
}
}
}
@@ -118,14 +117,6 @@ impl TunInterface {
iff
}
- #[throws]
- #[instrument]
- fn in6_ifreq(&self) -> sys::in6_ifreq {
- let mut iff: sys::in6_ifreq = unsafe { mem::zeroed() };
- iff.ifr_name = string_to_ifname(&self.name()?);
- iff
- }
-
#[throws]
#[instrument]
pub fn set_ipv4_addr(&self, addr: Ipv4Addr) {
@@ -145,21 +136,6 @@ impl TunInterface {
Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr))
}
- #[throws]
- pub fn set_ipv6_addr(&self, addr: Ipv6Addr) {
- // let addr = SockAddr::from(SocketAddrV6::new(addr, 0, 0, 0));
- // println!("addr: {:?}", addr);
- // let mut iff = self.in6_ifreq()?;
- // let sto = addr.as_storage();
- // let ifadddr_ptr: *const sockaddr_in6 = addr_of!(sto).cast();
- // iff.ifr_ifru.ifru_addr = unsafe { *ifadddr_ptr };
- // println!("ifru addr set");
- // println!("{:?}", sys::SIOCSIFADDR_IN6);
- // self.perform6(|fd| unsafe { sys::if_set_addr6(fd, &iff) })?;
- // tracing::info!("ipv6_addr_set");
- tracing::warn!("Setting IPV6 address on MacOS CLI mode is not supported yet.");
- }
-
#[throws]
fn perform(&self, perform: impl FnOnce(RawFd) -> Result) -> R {
let span = tracing::info_span!("perform", fd = self.as_raw_fd());
@@ -169,15 +145,6 @@ impl TunInterface {
perform(socket.as_raw_fd())?
}
- #[throws]
- fn perform6(&self, perform: impl FnOnce(RawFd) -> Result) -> R {
- let span = tracing::info_span!("perform6", fd = self.as_raw_fd());
- let _enter = span.enter();
-
- let socket = Socket::new(Domain::IPV6, Type::DGRAM, None)?;
- perform(socket.as_raw_fd())?
- }
-
#[throws]
#[instrument]
pub fn mtu(&self) -> i32 {
diff --git a/tun/src/unix/apple/sys.rs b/tun/src/unix/apple/sys.rs
index d48d6ee..b4d4a6a 100644
--- a/tun/src/unix/apple/sys.rs
+++ b/tun/src/unix/apple/sys.rs
@@ -1,6 +1,6 @@
use std::mem;
-use libc::{c_char, c_int, c_short, c_uint, c_ulong, sockaddr, sockaddr_in6, time_t};
+use libc::{c_char, c_int, c_short, c_uint, c_ulong, sockaddr};
pub use libc::{
c_void,
sockaddr_ctl,
@@ -23,7 +23,6 @@ pub const UTUN_CONTROL_NAME: &str = "com.apple.net.utun_control";
pub const UTUN_OPT_IFNAME: libc::c_int = 2;
pub const MAX_KCTL_NAME: usize = 96;
-pub const SCOPE6_ID_MAX: usize = 16;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
@@ -75,107 +74,7 @@ pub struct ifreq {
pub ifr_ifru: ifr_ifru,
}
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct in6_addrlifetime{
- pub ia6t_expire: time_t,
- pub ia6t_preferred: time_t,
- pub ia6t_vltime: u32,
- pub ia6t_pltime: u32,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct in6_ifstat {
- pub ifs6_in_receive: u64,
- pub ifs6_in_hdrerr: u64,
- pub ifs6_in_toobig: u64,
- pub ifs6_in_noroute: u64,
- pub ifs6_in_addrerr: u64,
- pub ifs6_in_protounknown: u64,
- pub ifs6_in_truncated: u64,
- pub ifs6_in_discard: u64,
- pub ifs6_in_deliver: u64,
- pub ifs6_out_forward: u64,
- pub ifs6_out_request: u64,
- pub ifs6_out_discard: u64,
- pub ifs6_out_fragok: u64,
- pub ifs6_out_fragfail: u64,
- pub ifs6_out_fragcreat: u64,
- pub ifs6_reass_reqd: u64,
- pub ifs6_reass_ok: u64,
- pub ifs6_atmfrag_rcvd: u64,
- pub ifs6_reass_fail: u64,
- pub ifs6_in_mcast: u64,
- pub ifs6_out_mcast: u64,
- pub ifs6_cantfoward_icmp6: u64,
- pub ifs6_addr_expiry_cnt: u64,
- pub ifs6_pfx_expiry_cnt: u64,
- pub ifs6_defrtr_expiry_cnt: u64,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone, Debug)]
-pub struct icmp6_ifstat {
- pub ifs6_in_msg: u64,
- pub ifs6_in_error: u64,
- pub ifs6_in_dstunreach: u64,
- pub ifs6_in_adminprohib: u64,
- pub ifs6_in_timeexceed: u64,
- pub ifs6_in_paramprob: u64,
- pub ifs6_in_pkttoobig: u64,
- pub ifs6_in_echo: u64,
- pub ifs6_in_echoreply: u64,
- pub ifs6_in_routersolicit: u64,
- pub ifs6_in_routeradvert: u64,
- pub ifs6_in_neighborsolicit: u64,
- pub ifs6_in_neighboradvert: u64,
- pub ifs6_in_redirect: u64,
- pub ifs6_in_mldquery: u64,
- pub ifs6_in_mldreport: u64,
- pub ifs6_in_mlddone: u64,
- pub ifs6_out_msg: u64,
- pub ifs6_out_error: u64,
- pub ifs6_out_dstunreach: u64,
- pub ifs6_out_adminprohib: u64,
- pub ifs6_out_timeexceed: u64,
- pub ifs6_out_paramprob: u64,
- pub ifs6_out_pkttoobig: u64,
- pub ifs6_out_echo: u64,
- pub ifs6_out_echoreply: u64,
- pub ifs6_out_routersolicit: u64,
- pub ifs6_out_routeradvert: u64,
- pub ifs6_out_neighborsolicit: u64,
- pub ifs6_out_neighboradvert: u64,
- pub ifs6_out_redirect: u64,
- pub ifs6_out_mldquery: u64,
- pub ifs6_out_mldreport: u64,
- pub ifs6_out_mlddone: u64,
-}
-
-#[repr(C)]
-pub union ifr_ifru6 {
- pub ifru_addr: sockaddr_in6,
- pub ifru_dstaddr: sockaddr_in6,
- pub ifru_flags: c_int,
- pub ifru_flags6: c_int,
- pub ifru_metric: c_int,
- pub ifru_intval: c_int,
- pub ifru_data: *mut c_char,
- pub ifru_lifetime: in6_addrlifetime, // ifru_lifetime
- pub ifru_stat: in6_ifstat,
- pub ifru_icmp6stat: icmp6_ifstat,
- pub ifru_scope_id: [u32; SCOPE6_ID_MAX]
-}
-
-#[repr(C)]
-pub struct in6_ifreq {
- pub ifr_name: [c_char; IFNAMSIZ],
- pub ifr_ifru: ifr_ifru6,
-}
-
pub const SIOCSIFADDR: c_ulong = request_code_write!(b'i', 12, mem::size_of::());
-pub const SIOCSIFADDR_IN6: c_ulong = request_code_write!(b'i', 12, mem::size_of::());
pub const SIOCGIFMTU: c_ulong = request_code_readwrite!(b'i', 51, mem::size_of::());
pub const SIOCSIFMTU: c_ulong = request_code_write!(b'i', 52, mem::size_of::());
pub const SIOCGIFNETMASK: c_ulong = request_code_readwrite!(b'i', 37, mem::size_of::());
@@ -198,6 +97,5 @@ ioctl_read_bad!(if_get_addr, libc::SIOCGIFADDR, ifreq);
ioctl_read_bad!(if_get_mtu, SIOCGIFMTU, ifreq);
ioctl_read_bad!(if_get_netmask, SIOCGIFNETMASK, ifreq);
ioctl_write_ptr_bad!(if_set_addr, SIOCSIFADDR, ifreq);
-ioctl_write_ptr_bad!(if_set_addr6, SIOCSIFADDR_IN6, in6_ifreq);
ioctl_write_ptr_bad!(if_set_mtu, SIOCSIFMTU, ifreq);
ioctl_write_ptr_bad!(if_set_netmask, SIOCSIFNETMASK, ifreq);
diff --git a/tun/tests/packets.rs b/tun/tests/packets.rs
index 80c078b..28090a2 100644
--- a/tun/tests/packets.rs
+++ b/tun/tests/packets.rs
@@ -1,5 +1,4 @@
use std::{io::Error, net::Ipv4Addr};
-use std::net::Ipv6Addr;
use fehler::throws;
use tun::TunInterface;
@@ -34,15 +33,3 @@ fn write_packets() {
let bytes_written = tun.send(&buf)?;
assert_eq!(bytes_written, 1504);
}
-
-#[test]
-#[throws]
-#[ignore = "requires interactivity"]
-#[cfg(not(target_os = "windows"))]
-fn set_ipv6() {
- let tun = TunInterface::new()?;
- println!("tun name: {:?}", tun.name()?);
- let targ_addr: Ipv6Addr = "::1".parse().unwrap();
- println!("v6 addr: {:?}", targ_addr);
- tun.set_ipv6_addr(targ_addr)?;
-}
\ No newline at end of file