             cancel()
         case .Cancelled:
             DDLogVerbose("Cancelled")
-            if !cancelledSignaled {
-                cancelledSignaled = true
-                delegateCall() {
-                    self.delegate?.didDisconnect(self)
-                }
+            queueCall {
+                self.delegate?.didDisconnect(self)
+                self.delegate = nil
             }
         default:
             DDLogVerbose("SNWTunnel state is \(connection.state.rawValue).")

                return
            }

            self.delegateCall() {
                self.delegate?.didWriteData(data, withTag: tag, from: self)
            }
            self.checkStatus()

    var scannerTag: Int!
    var readDataPrefix: NSData?

    // MARK: RawTCPSocketProtocol implemention

    /// The `RawTCPSocketDelegate` instance.
    weak var delegate: RawTCPSocketDelegate?

    /// Every method call and variable access must operated on this queue. And all delegate methods will be called on this queue.
    ///
    /// - warning: This should be set as soon as the instance is initialized.
    var queue: dispatch_queue_t!

    /// If the socket is connected.
    var isConnected: Bool {
        return connection.state == .Connected
    }

    /// The source address.
    ///
    /// - note: Always returns `nil`.
    var sourceIPAddress: IPv4Address? {
        return nil
    }

    /// The source port.
    ///
    /// - note: Always returns `nil`.
    var sourcePort: Port? {
        return nil
    }

    /// The destination address.
    ///
    /// - note: Always returns `nil`.
    var destinationIPAddress: IPv4Address? {
        return nil
    }

    /// The destination port.
    ///
    /// - note: Always returns `nil`.
    var destinationPort: Port? {
        return nil
    }

    /**
     Connect to remote host.

     - parameter host:        Remote host.
     - parameter port:        Remote port.
     - parameter enableTLS:   Should TLS be enabled.
     - parameter tlsSettings: The settings of TLS.

     - throws: Never throws.
     */
    func connectTo(host: String, port: Int, enableTLS: Bool, tlsSettings: [NSObject : AnyObject]?) throws {
        let endpoint = NWHostEndpoint(hostname: host, port: "\(port)")
        let tlsParameters = NWTLSParameters()
        if let tlsSettings = tlsSettings as? [String: AnyObject] {
