def probeUserOnline(self, publicKey, callback=None): assert self.sm.current() == self.ONLINE def onStateChange(): lookupOp.cancel() op.notify(False) def doCancel(): lookupOp.cancel() self.sm.removeCallback(callbackId) def onLookup(location): self.sm.removeCallback(callbackId) if location is None: op.notify(False) return if (not location.directLocations) and ( not location.routedLocations): op.notify(False) return op.notify(True) lookupOp = self.locationCache.refreshUser(publicKey, onLookup) callbackId = self.sm.insertCallback(onStateChange, src=self.ONLINE, single=True) op = AsyncOp(callback, doCancel) return op
def acceptIncoming(acceptFlag, sslConn, reactor, callback=None): def doCancel(): stream.close() def onError(*args): doCancel() op.notify(None) def onWriteComplete(): stream.shutdown() op.notify(sslConn) stream = SSLMessageStream(sslConn, reactor) stream.setCloseCallback(onError) stream.setErrorCallback(onError) stream.setInvalidMessageCallback(onError) stream.setInputCallback(onError) stream.setWriteCompleteCallback(onWriteComplete) if acceptFlag: data = 0 else: data = -1 stream.sendMessage(encode(data)) op = AsyncOp(callback, doCancel) return op
def routerAccept( routerAddr, connectionId, reactor, callback=None ) : obj = Dummy() def doCancel() : if obj.op : obj.op.cancel() if obj.rpcConn : obj.rpcConn.close() def onError() : doCancel() op.notify( None ) def onRouterAccept( err, result ) : obj.op = None if err < 0 : onError() return sock = obj.rpcConn.getSock() obj.rpcConn.shutdown() op.notify( sock ) def onTCPConnect( connector ) : obj.op = None if connector.getError() != 0 : onError() return obj.rpcConn = RPCConnection( connector.getSock(), reactor ) obj.rpcConn.setCloseCallback( onError ) obj.op = _doRPCCall( obj.rpcConn, 'Accept', [connectionId], onRouterAccept ) obj.op = tcpConnect( routerAddr, reactor, onTCPConnect ) op = AsyncOp( callback, doCancel ) obj.rpcConn = None return op
def _registerKey(self, callback=None): data = 'username:%s' % self.userName digestType = DigestType('SHA1') digest = Digest(digestType).digest(data) signature = self.rsaKey.sign(digest, digestType) form = dict(username=self.userName, public_key=self.rsaKey.toDER_PublicKey(), signature=signature) postData = urllib.urlencode(form) request = HttpRequest(self.reactor) def onResponse(returnCode, data): if returnCode != 200: op.notify(-1) return try: keyId = int(data) op.notify(keyId) except ValueError: op.notify(-1) httpOp = request.post('http://cspace.in/addkey', postData, onResponse) op = AsyncOp(callback, httpOp.cancel) return op
def _sslHandshake(sock, sslContext, reactor, callback=None): def doCancel(): acceptOp.cancel() sslAbort(sslConn) def onSSLAccept(err): if err is not None: sslAbort(sslConn) op.notify(None) return try: peerCert = sslConn.getPeerCertificate() peerKey = peerCert.getPublicKey() peerName = peerCert.getSubject().lookupEntry('commonName') except (SSLError, X509Error): sslAbort(sslConn) op.notify(None) return data = (sslConn, peerKey, peerName) op.notify(data) sslConn = SSLConnection(sslContext, sock) acceptOp = sslAccept(sslConn, reactor, onSSLAccept) op = AsyncOp(callback, doCancel) return op
def _serviceConnect( sslConn, serviceName, reactor, callback=None ) : def doCancel() : ms.shutdown() sslAbort( sslConn ) def onClose( *args ) : doCancel() op.notify( None ) def onInput( data ) : try : result = decode( data ) assert type(result) is int assert result == 0 except : doCancel() op.notify( None ) return ms.shutdown() op.notify( sslConn ) ms = SSLMessageStream( sslConn, reactor ) ms.setCloseCallback( onClose ) ms.setErrorCallback( onClose ) ms.setInvalidMessageCallback( onClose ) ms.setInputCallback( onInput ) ms.sendMessage( encode(serviceName) ) ms.enableRead( True ) op = AsyncOp( callback, doCancel ) return op
def _initNodeRefresher(self): obj = Dummy() def doWait(): timeout = REFRESH_NODES_INTERVAL obj.op = self.reactor.callLater(timeout, doRefresh) def onLookup(nodes): doWait() def doRefresh(): bucket = choice(self.ktable.table) destNumId = randint(bucket.start, bucket.end - 1) destId = numToId(destNumId) startNodes = self.ktable.getClosestNodes(destNumId) if not startNodes: doWait() return obj.op = self.client.lookup(destId, startNodes, onLookup) def doCancel(): obj.op.cancel() obj.op = self.reactor.callLater(0, doRefresh) op = AsyncOp(None, doCancel) self.otherOps.add(op)
def refreshUser(self, publicKey, callback=None): pubKeyData = publicKey.toDER_PublicKey() entry = self.d.get(pubKeyData) if entry is None: entry = _Entry(publicKey) self.d[pubKeyData] = entry assert entry.state != ES_NOTIFYING if entry.state == ES_DEFAULT: assert entry.lookupOp is None assert entry.notifyOps is None def onLookupUser(location): self._onLookupUser(entry, location) entry.lookupOp = lookupUser( publicKey, self.dhtClient, self.nodeTable, lambda loc: self._onLookupUser(entry, loc)) entry.state = ES_LOOKINGUP entry.notifyOps = set() def doCancel(): entry.notifyOps.remove(op) op = AsyncOp(callback, doCancel) entry.notifyOps.add(op) return op
def _promptIncoming(self, sslConn, serviceName, peerKey, contactName, incomingName, callback=None): def doCancel(): promptOp.cancel() sslAbort(sslConn) def onPromptResult(promptResult): if not promptResult: rejectOp = self._rejectIncoming(sslConn, op.notify) op.setCanceler(rejectOp.cancel) else: acceptOp = self._acceptIncoming(sslConn, serviceName, peerKey, contactName, incomingName, op.notify) op.setCanceler(acceptOp.cancel) promptName = contactName if not promptName: promptName = '(Unknown %s)' % incomingName promptOp = IncomingPromptWindow(promptName, serviceName, self.reactor, onPromptResult).getOp() op = AsyncOp(callback, doCancel) return op
def connectTo(self, publicKey, serviceName, callback=None): assert self.sm.current() == self.ONLINE def onStateChange(): connectOp.cancel() op.notify(-1, None) def doCancel(): connectOp.cancel() self.sm.removeCallback(callbackId) def onConnect(sslConn): self.sm.removeCallback(callbackId) if sslConn is None: op.notify(-1, None) return op.notify(0, sslConn) connectOp = userServiceConnect(self.profile.name, self.profile.rsaKey, self.listener.getPublicIP(), publicKey, serviceName, self.locationCache, self.reactor, onConnect) callbackId = self.sm.insertCallback(onStateChange, src=self.ONLINE, single=True) op = AsyncOp(callback, doCancel) return op
def lookup( self, destId, startNodes, callback=None ) : def hookCallback( *args, **kwargs ) : print 'done lookup %s' % str(id(lop)) op.notify( *args, **kwargs ) lop = _Lookup( self, destId, startNodes, hookCallback ).getOp() print 'starting lookup... %s' % str(id(lop)) op = AsyncOp( callback, lop.cancel ) return op
def __init__(self, reactor, callback=None): assert env.isContactAction or env.isIncoming self.reactor = reactor self.op = AsyncOp(callback, self._doCancel) self.state = self.CONNECTING self.connectOp = tcpConnect(('127.0.0.1', env.port), self.reactor, self._onConnect) self.stream = None
def __init__(self, curlHandle, reactor, callback=None): self.reactor = reactor self.cm = pycurl.CurlMulti() self.c = curlHandle self.cm.add_handle(self.c) self.fdsets = ([], [], []) self.timerOp = self.reactor.callLater(0, self._onInitialTimer) self.op = AsyncOp(callback, self._doCancel)
def __init__(self, sock, connectionId, reactor, callback): self.stream = TCPStream(sock, reactor) self.stream.setCloseCallback(self._onClose) self.stream.setErrorCallback(self._onError) self.stream.setInputCallback(self._onInput) self.stream.initiateRead(1) self.stream.writeData('ACCEPT %s\r\n' % connectionId) self.response = '' self.op = AsyncOp(callback, self.stream.close)
def _findLiveNodes(count, nodeTable, dhtClient, reactor, callback=None): obj = Dummy() def doCancel(): for pingOp in obj.pingOps: pingOp.cancel() obj.pingOps.clear() obj.timerOp.cancel() obj.timerOp = None def doNotify(): doCancel() op.notify() def onPing(pingOp, err, payload): obj.pingOps.remove(pingOp) if err >= 0: obj.success += 1 if obj.success >= count: doNotify() elif (not obj.nodes) and (not obj.pingOps): doNotify() def doPing(nodeAddr): pingOp = dhtClient.callPing(nodeAddr, lambda e, p: onPing(pingOp, e, p)) obj.pingOps.add(pingOp) def doPingNodes(count): current = obj.nodes[:count] del obj.nodes[:count] for nodeAddr in current: doPing(nodeAddr) def onTimer(): obj.timerCount += 1 if not obj.pingedSeed: if (not obj.nodes) or (obj.timerCount == \ FIND_LIVE_NODES_TIMEOUT_COUNT ) : for nodeAddr in nodeTable.getSeedNodes(): doPing(nodeAddr) obj.pingedSeed = True return if not obj.nodes: return doPingNodes(10) obj.success = 0 obj.pingOps = set() obj.nodes = nodeTable.getAllNodes() doPingNodes(10) obj.timerCount = 0 obj.pingedSeed = False obj.timerOp = reactor.addTimer(FIND_LIVE_NODES_TIMEOUT, onTimer) op = AsyncOp(callback, doCancel) return op
def initNodeTable(nodeTable, dhtClient, reactor, callback=None): def onFindLive(): print 'done finding live nodes' findNewOp = _findNewNodes(nodeTable, dhtClient, reactor, op.notify) op.setCanceler(findNewOp.cancel) print 'finding live nodes...' findLiveOp = _findLiveNodes(5, nodeTable, dhtClient, reactor, onFindLive) op = AsyncOp(callback, findLiveOp.cancel) return op
def _findNewNodes(nodeTable, dhtClient, reactor, callback=None): destId = numToId(randint(0, DHT_ID_MAX - 1)) startNodes = nodeTable.getLiveNodes() def onLookup(nodes): op.notify() lookupOp = dhtClient.lookup(destId, startNodes, onLookup) op = AsyncOp(callback, lookupOp.cancel) return op
def listAllMappings( device, reactor, callback=None ) : mappings = [] def onResponse( mapping ) : if mapping is not None : mappings.append( mapping ) return op.notify( mappings ) listOp = UPnpActions.listMappings( device, reactor, onResponse ) op = AsyncOp( callback, listOp.cancel ) return op
def callAction( self, name, params, reactor, callback=None ) : payload = self.getActionPayload( name, params ) http = HttpRequest( reactor ) http.addHeader( 'Content-Type: text/xml; charset="utf-8"' ) http.addHeader( 'SOAPACTION: "%s#%s"' % (self.service,name) ) def onResponse( result, data ) : self._onActionResponse( op, name, result, data ) httpOp = http.post( self.controlUrl, payload, onResponse ) op = AsyncOp( callback, httpOp.cancel ) return op
def __init__(self, sock, remoteUser, remoteService, reactor, callback): self.stream = TCPStream(sock, reactor) self.stream.setCloseCallback(self._onClose) self.stream.setErrorCallback(self._onError) self.stream.setInputCallback(self._onInput) self.stream.initiateRead(1) self.stream.writeData('CONNECT %s %s\r\n' % (remoteUser, remoteService)) self.response = '' self.op = AsyncOp(callback, self.stream.close)
def delMapping( device, externalPort, protocol, reactor, callback=None ) : assert protocol in ('TCP','UDP') params = { 'NewRemoteHost' : '', 'NewExternalPort' : externalPort, 'NewProtocol' : protocol } def onResponse( result, data ) : op.notify( result == 0 ) actionOp = device.callAction( 'DeletePortMapping', params, reactor, onResponse ) op = AsyncOp( callback, actionOp.cancel ) return op
def getExternalIP( device, reactor, callback=None ) : def onResponse( result, data ) : if result < 0 : op.notify( None ) return externalIP = dict(data).get('NewExternalIPAddress',None) op.notify( externalIP ) actionOp = device.callAction( 'GetExternalIPAddress', {}, reactor, onResponse ) op = AsyncOp( callback, actionOp.cancel ) return op
def _rejectIncoming(self, sslConn, callback=None): def onReject(sslConn): if sslConn is None: op.notify(False) return sslAbort(sslConn) op.notify(True) rejectOp = acceptIncoming(False, sslConn, self.reactor, onReject) op = AsyncOp(callback, rejectOp.cancel) return op
def cspaceAccept(cspaceAddr, connectionId, reactor, callback): def onTCPConnect(connector): if connector.getError() != 0: op.notify(-1, None) return acceptOp = CSpaceAcceptor(connector.getSock(), connectionId, reactor, op.notify).getOp() op.setCanceler(acceptOp.cancel) tcpOp = tcpConnect(cspaceAddr, reactor, onTCPConnect) op = AsyncOp(callback, tcpOp.cancel) return op
def _directConnect( sslContext, remotePublicKey, directLocation, reactor, callback=None ) : def onConnect( connector ) : if connector.getError() != 0 : op.notify( None ) return authOp = _authenticateUser( connector.getSock(), sslContext, remotePublicKey, reactor, op.notify ) op.setCanceler( authOp.cancel ) connectOp = tcpConnect( directLocation.addr, reactor, onConnect ) op = AsyncOp( callback, connectOp.cancel ) return op
def __init__(self, fileClient, remotePath, localPath, callback=None): self.fileClient = fileClient self.remotePath = remotePath self.localPath = localPath self.out = file(localPath, 'w+b') self.sizeOp = self.fileClient.callGetSize(remotePath, self._onGetSize) self.fileSize = -1 self.op = AsyncOp(callback, self._doCancel) self.blockSize = 16384 self.requestedSize = 0 self.receivedSize = 0 self.fetchOps = {}
def cspaceConnect(cspaceAddr, remoteUser, remoteService, reactor, callback): def onTCPConnect(connector): if connector.getError() != 0: op.notify(-1, None) return connectOp = CSpaceConnector(connector.getSock(), remoteUser, remoteService, reactor, op.notify).getOp() op.setCanceler(connectOp.cancel) tcpOp = tcpConnect(cspaceAddr, reactor, onTCPConnect) op = AsyncOp(callback, tcpOp.cancel) return op
def _routedConnect( sslContext, remotePublicKey, routerLocation, reactor, callback=None ) : def onConnect( sock ) : if sock is None : op.notify( None ) return authOp = _authenticateUser( sock, sslContext, remotePublicKey, reactor, op.notify ) op.setCanceler( authOp.cancel ) connectOp = routerConnect( routerLocation.routerAddr, routerLocation.routerId, reactor, onConnect ) op = AsyncOp( callback, connectOp.cancel ) return op
def __init__( self, clientObj, destId, startNodes, callback=None ) : assert startNodes self.clientObj = clientObj self.destId = destId self.destNumId = idToNum( destId ) self.seen = {} self.closest = [] self.pending = [] self.calling = {} for nodeAddr in startNodes : self._newNode( nodeAddr ) self._callPending() self.op = AsyncOp( callback, self._doCancel )
def publishUserLocation(rsaKey, location, updateLevel, dhtClient, nodeTable, callback=None): def onResult(putCount, updateLevel): op.notify(putCount > 0, updateLevel) dhtOp = dhtClient.lookupPutKey(rsaKey, location.encode(), updateLevel, nodeTable.getLiveNodes(), onResult) op = AsyncOp(callback, dhtOp.cancel) return op