Попытка отслеживать изменения SystemConfiguration (сеть) в Swift, но код не работает (об изменениях не сообщается) - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь написать простую утилиту, которая следит за текущим состоянием SystemConfiguration сетевых интерфейсов и завершает работу при возникновении любого из следующих событий:

  • Сетевой интерфейс появляется или исчезает
  • IPv4 или IPv6-адрес в сетевом интерфейсе изменяется

Я написал программу, которая компилируется и запускается, но когда я запускаю / останавливаю свой VPN, программа не обнаруживает никаких изменений, т.е. обратный вызовникогда не называется. Кто-нибудь знает, в чем может быть проблема? Вот код ...

import Foundation
import CoreFoundation
import SystemConfiguration

var nwChange = false


func displayUsage() {
    print("\nUsage:\n")
    print("    netwatcher\n")
    exit(20)
}

func CreateIPAddressListChangeCallbackSCF(
                                          _ rl:CFRunLoop
                                         ) -> Int
{
    var ctxt = SCDynamicStoreContext()
    var patterns = [CFString]()
    let callback: SCDynamicStoreCallBack = { (cstore, _, _) in
        nwChange = true
        print("Something changed!")
    }

    let store = SCDynamicStoreCreate( nil, "netwatcher" as CFString, callback, &ctxt )
    if store == nil {
        print("error: failed to create dynamic store");
        return 9
    }

    patterns.append( SCDynamicStoreKeyCreateNetworkInterfaceEntity( nil, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetInterface ) )

    patterns.append( SCDynamicStoreKeyCreateNetworkInterfaceEntity( nil, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4 ) )
    patterns.append( SCDynamicStoreKeyCreateNetworkInterfaceEntity( nil, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6 ) )

    if !SCDynamicStoreSetNotificationKeys( store!, nil, patterns as CFArray ) {
        print("error: failed to set notification keys");
        return 5
    }

    if let rls = SCDynamicStoreCreateRunLoopSource( nil, store!, 0 ) {
        CFRunLoopAddSource( rl, rls, .commonModes )
    } else {
        print("error: failed to create run loop source")
        return 4
    }

    return 0
}

let args = CommandLine.arguments
if args.count > 1 {
    displayUsage()
}

let runLoop = CFRunLoopGetCurrent()
if runLoop == nil {
    print("error: unable to get my run loop")
    exit( 10 )
}

let ret = CreateIPAddressListChangeCallbackSCF( runLoop! )
if ret != 0 {
    exit( Int32(ret) )
}

while !nwChange {
    sleep( 1 )
}

exit( 0 )
...