ursachec / CPAProxy

A thin Objective-C wrapper around Tor.
Other
161 stars 49 forks source link

Crash in CPAProxyManager.m #42

Closed rushabh0999 closed 7 years ago

rushabh0999 commented 8 years ago

When i run, app returns EXC_BAD_ACCESS in Xcode 7.0 adn Xcode 7.3. Please suggest me to resolve this issue. Please find attached screenshot for reference. screen shot 2016-04-18 at 2 27 06 pm

SteffenKeller commented 8 years ago

I got the same error when calling cpaProxyManager setupWithCompletion. Any suggestions?

rainwolf commented 8 years ago

Is your cpaProxyManager an instance variable? Otherwise it will become nil when you exit the method where it was instantiated, and you'd get this error.

SteffenKeller commented 8 years ago

Oh, yes you're right. Thank you @rainwolf !

bucky0970 commented 7 years ago

I think my cpaProxyManager is an instance variable. But I still get this error

- (void)viewDidLoad {
    [super viewDidLoad];
    NSURL *cpaProxyBundleURL = [[NSBundle bundleForClass:[CPAProxyManager class]] URLForResource:@"CPAProxy" withExtension:@"bundle"];
    NSBundle *cpaProxyBundle = [NSBundle bundleWithURL:cpaProxyBundleURL];
    NSString *torrcPath = [cpaProxyBundle pathForResource:@"torrc" ofType:nil];
    NSString *geoipPath = [cpaProxyBundle pathForResource:@"geoip" ofType:nil];

    // Place to store Tor caches (non-temp storage improves performance since
    // directory data does not need to be re-loaded each launch)
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *torDataDir = [documentsDirectory stringByAppendingPathComponent:@"tor"];

    // Initialize a CPAProxyManager
    CPAConfiguration *configuration = [CPAConfiguration configurationWithTorrcPath:torrcPath geoipPath:geoipPath torDataDirectoryPath:torDataDir];
    CPAProxyManager *cpaProxyManager = [CPAProxyManager proxyWithConfiguration:configuration];
    // Do any additional setup after loading the view, typically from a nib.

    [cpaProxyManager setupWithCompletion:^(NSString *socksHost, NSUInteger socksPort, NSError *error) {
        if (error == nil) {
            // ... do something with Tor socks hostname & port ...
            NSLog(@"Connected: host=%@, port=%lu", socksHost, (long)socksPort);

            // ... like this -- see below for implementation ...
            [self handleCPAProxySetupWithSOCKSHost:socksHost SOCKSPort:socksPort];
        }
    } progress:^(NSInteger progress, NSString *summaryString) {
        // ... do something to notify user of tor's initialization progress ...
        NSLog(@"%li %@", (long)progress, summaryString);
    }];

}
rainwolf commented 7 years ago

If you literally used the code you pasted, then it's not an instance variable, you declared it locally with CPAProxyManager *cpaProxyManager = [CPAProxyManager proxyWithConfiguration:configuration];

If you did declare it as in instance variable, then changing that line to cpaProxyManager = [CPAProxyManager proxyWithConfiguration:configuration]; should work and no longer produce that error.

bucky0970 commented 7 years ago

1.Thanks for reply, I am new to Obj-C from swift. So I declare in top of my .m.

@interface ViewController ()
@property (nonatomic, strong, readwrite) CPAProxyManager *cpaProxyManager;
@end

Is this cpaProxyManager become instance variable? 2.I can get Bootstrapped 100%, but here comes some error

2016-12-27 17:00:47.097801 CPAProxyTest[79917:952972] [] ____nwlog_simulate_crash_inner_block_invoke dlopen CrashReporterSupport failed
2016-12-27 17:00:47.098206 CPAProxyTest[79917:952972] [] __nwlog_err_simulate_crash simulate crash failed "nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available"
2016-12-27 17:00:47.099120 CPAProxyTest[79917:952972] [] nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available, dumping backtrace:

Sorry to bother you, maybe my question is very noob...

update: I found stack overflow solution, There's no SO_NOAPNFALLBK socket option in man socket. I guess, this option is added by Apple and is related to push notifications services, which are not available on simulator. I will try it in my project, thanks for you help!

rainwolf commented 7 years ago

Even without declaring it as a property, the following should work out of the box. @implementation ViewController CPAProxyManager *cpaProxyManager;

bucky0970 commented 7 years ago

Thanks for you advise, I already change the code in swift, and it seems work properly. I will start doing some test with it! If anyone need swift version tutorial, here it is: First you need let the class you want to use CPAProxy implement URLSessionDelegate class TorViewController: UIViewController, URLSessionDelegate { In viewdidload

let cpaProxyBundleURL = Bundle(for: CPAProxyManager.self).url(forResource: "CPAProxy", withExtension: "bundle")
        if let cpaProxyBundle = Bundle(url: cpaProxyBundleURL!) {

            let torrcPath = cpaProxyBundle.path(forResource: "torrc", ofType: nil)!
            let geoipPath = cpaProxyBundle.path(forResource: "geoip", ofType: nil)!
            // Place to store Tor caches (non-temp storage improves performance since
            // directory data does not need to be re-loaded each launch)
            let documentsDirectory =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let torDataDir = documentsDirectory.path + "/tor"

            // Initialize a CPAProxyManager
            let configuration = CPAConfiguration (torrcPath: torrcPath, geoipPath: geoipPath, torDataDirectoryPath: torDataDir)

            cpaProxyManager = CPAProxyManager.proxy(with: configuration)
            // Do any additional setup after loading the view, typically from a nib.
            cpaProxyManager.setup(completion: {socksHost,socksPort,error -> Void in
                print("finish setup")
                if error == nil {
                    // ... do something with Tor socks hostname & port ...
                    print("Connected: host=\(socksHost), port=\(Int(socksPort))")
                    // ... like this -- see below for implementation ...
                    self.handleCPAProxySetup(withSOCKSHost: socksHost!, socksPort: Int(socksPort))
                }
            }, progress: {progress,summaryString -> Void in
                // ... do something to notify user of tor's initialization progress ...
                print("\(Int(progress)) \(summaryString)")
            })

        }else {

            assertionFailure("Could not load the bundle")

        } 
func handleCPAProxySetup(withSOCKSHost SOCKSHost: String, socksPort SOCKSPort: Int) {
        // Create a NSURLSessionConfiguration that uses the newly setup SOCKS proxy
        let proxyDict = [(kCFStreamPropertySOCKSProxyHost as String): SOCKSHost, (kCFStreamPropertySOCKSProxyPort as String): (SOCKSPort)] as [String : Any]
        let configuration = URLSessionConfiguration.ephemeral
        configuration.connectionProxyDictionary = proxyDict
        // Create a NSURLSession with the configuration
        let urlSession = URLSession(configuration: configuration,delegate: self, delegateQueue: OperationQueue.main)
        // Send an HTTP GET Request using NSURLSessionDataTask
        let URL = NSURL(string: "https://check.torproject.org")
        let dataTask = urlSession.dataTask(with: (URL?.absoluteURL)!)
        dataTask.resume()
        // ...
    } 
ddeneka commented 7 years ago

@chrisballinger this should be solved by https://github.com/ursachec/CPAProxy/commit/b6d8a4b66b79760b8e3468dc0dd052cc0ba72f11