def _verify_transport(proto): if _Debug: lg.out(_DebugLevel - 8, " verifying %s_transport" % proto) if not settings.transportIsEnabled(proto): if _Debug: lg.out(_DebugLevel - 8, " %s_transport is disabled" % proto) return succeed(True) transp = transport(proto) if transp.state == "OFFLINE": if _Debug: lg.out(_DebugLevel - 8, " %s_transport state is OFFLINE" % proto) return succeed(True) if transp.state != "LISTENING": if _Debug: lg.out(_DebugLevel - 8, " %s_transport state is not LISTENING" % proto) return succeed(True) transp_result = transp.interface.verify_contacts(my_id_obj) if _Debug: lg.out(_DebugLevel - 8, " %s result is %r" % (proto, transp_result)) if isinstance(transp_result, bool) and transp_result: return succeed(True) if isinstance(transp_result, bool) and transp_result == False: return succeed(False) if isinstance(transp_result, Deferred): ret = Deferred() transp_result.addCallback(lambda result_value: ret.callback(result_value)) return ret lg.warn("incorrect result returned from %s_interface.verify_contacts(): %r" % (proto, transp_result)) return succeed(False)
def _verify_transport(proto): if _Debug: lg.out(_DebugLevel - 8, ' verifying %s_transport' % proto) if not settings.transportIsEnabled(proto): if _Debug: lg.out(_DebugLevel - 8, ' %s_transport is disabled' % proto) return succeed(True) transp = transport(proto) if transp.state == 'OFFLINE': if _Debug: lg.out(_DebugLevel - 8, ' %s_transport state is OFFLINE' % proto) return succeed(True) if transp.state != 'LISTENING': if _Debug: lg.out(_DebugLevel - 8, ' %s_transport state is not LISTENING' % proto) return succeed(True) transp_result = transp.interface.verify_contacts(my_id_obj) if _Debug: lg.out(_DebugLevel - 8, ' %s result is %r' % (proto, transp_result)) if isinstance(transp_result, bool) and transp_result: return succeed(True) if isinstance(transp_result, bool) and transp_result == False: return succeed(False) if isinstance(transp_result, Deferred): ret = Deferred() transp_result.addCallback( lambda result_value: ret.callback(result_value)) return ret lg.warn( 'incorrect result returned from %s_interface.verify_contacts(): %r' % (proto, transp_result)) return succeed(False)
def cold_start(): """ """ if _Debug: lg.out( 4, 'gateway.cold_start : sending "start" only to one transport - most preferable' ) callback.append_outbox_filter_callback(on_outbox_packet) callback.add_finish_file_receiving_callback(on_file_received) ordered_list = transports().keys() ordered_list.sort(key=settings.getTransportPriority, reverse=True) result = [] for proto in ordered_list: transp = transport(proto) if settings.transportIsEnabled(proto): if transp.state != 'LISTENING': if _Debug: lg.out(4, ' sending "start" to %s and stop' % transp) transp.automat('start') result.append(proto) break else: if _Debug: lg.out(4, ' %r is ready, try next one' % transp) reactor.callLater(5, packets_timeout_loop) return result
def list_active_transports(): """ """ result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != 'OFFLINE': result.append(proto) return result
def list_active_transports(): """ """ result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != "OFFLINE": result.append(proto) return result
def list_active_transports(): """ """ if not is_ready(): return fail(Exception('gateway is not ready')) result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != 'OFFLINE': result.append(proto) return result
def start(): """ """ if _Debug: lg.out(4, 'gateway.start') callback.append_outbox_filter_callback(on_outbox_packet) result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != 'LISTENING': if _Debug: lg.out(4, ' sending "start" to %s' % transp) transp.automat('start') result.append(proto) else: if _Debug: lg.out(4, ' %r is ready' % transp) reactor.callLater(5, packets_timeout_loop) return result
def start(): """ """ if _Debug: lg.out(4, "gateway.start") callback.append_outbox_filter_callback(on_outbox_packet) result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != "LISTENING": if _Debug: lg.out(4, ' sending "start" to %s' % transp) transp.automat("start") result.append(proto) else: if _Debug: lg.out(4, " %r is ready" % transp) reactor.callLater(5, packets_timeout_loop) return result
def stop(): """ """ if _Debug: lg.out(4, "gateway.stop") stop_packets_timeout_loop() shutdown_all_inbox_packets() shutdown_all_outbox_packets() result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != "OFFLINE": if _Debug: lg.out(4, ' send "stop" to %s' % transp) transp.automat("stop") result.append(proto) else: if _Debug: lg.out(4, " %s already stopped" % proto) callback.remove_outbox_filter_callback(on_outbox_packet) return result
def stop(): """ """ if _Debug: lg.out(4, 'gateway.stop') stop_packets_timeout_loop() shutdown_all_inbox_packets() shutdown_all_outbox_packets() result = [] for proto, transp in transports().items(): if settings.transportIsEnabled(proto): if transp.state != 'OFFLINE': if _Debug: lg.out(4, ' send "stop" to %s' % transp) transp.automat('stop') result.append(proto) else: if _Debug: lg.out(4, ' %s already stopped' % proto) callback.remove_finish_file_receiving_callback(on_file_received) callback.remove_outbox_filter_callback(on_outbox_packet) return result
def cold_start(): """ """ if _Debug: lg.out(4, 'gateway.cold_start : sending "start" only to one transport - most preferable') callback.append_outbox_filter_callback(on_outbox_packet) ordered_list = transports().keys() ordered_list.sort(key=settings.getTransportPriority, reverse=True) result = [] for proto in ordered_list: transp = transport(proto) if settings.transportIsEnabled(proto): if transp.state != "LISTENING": if _Debug: lg.out(4, ' sending "start" to %s and stop' % transp) transp.automat("start") result.append(proto) break else: if _Debug: lg.out(4, " %r is ready, try next one" % transp) reactor.callLater(5, packets_timeout_loop) return result
def buildProtoContacts(id_obj, skip_transports=[]): """ Create a full list of needed transport methods to be able to accept incoming traffic from other nodes. Make calls to transport services to build a list of my contacts. """ from services import driver # prepare contacts current_contats = id_obj.getContactsByProto() current_order = id_obj.getProtoOrder() lg.out(4, 'my_id.buildProtoContacts') lg.out(4, ' current contacts: %s' % str(current_contats)) lg.out(4, ' current order: %s' % str(current_order)) new_contacts = {} new_order_correct = [] # prepare list of active transports active_transports = [] for proto in getValidTransports(): if proto in skip_transports: continue if not settings.transportIsEnabled(proto): continue if not settings.transportReceivingIsEnabled(proto): continue if not driver.is_on('service_%s_transport' % proto): lg.warn( 'transport "%s" is enabled, but service_%s_transport() is not ready yet' % (proto, proto)) continue active_transports.append(proto) # sort active transports by priority lg.out(4, ' active transports: %s' % str(active_transports)) active_transports.sort(key=settings.getTransportPriority) lg.out(4, ' sorted transports: %s' % str(active_transports)) if not driver.is_on('service_gateway'): new_contacts = current_contats new_order_correct = current_order else: from transport import gateway # build contacts data according transports priorities new_order = current_order for proto in active_transports: clist = gateway.transport(proto).interface.build_contacts(id_obj) cdict = {} corder = [] for contact in clist: cproto, _ = contact.split(b'://') cdict[cproto] = contact corder.append(cproto) new_contacts.update(cdict) for cproto in corder: if cproto not in new_order: new_order.append(cproto) new_order_correct = list(new_order) for nproto in new_order: if nproto not in list(new_contacts.keys()): new_order_correct.remove(nproto) # cset = set(corder) # cdiff = cset.intersection(current_set) # if cset.isdisjoint() # # # if len(clist) > 1: # # clist.reverse() # for contact in clist: # cproto, cdata = contact.split('://') # cdict[cproto] = contact # if cproto in new_order: # new_order.remove(cproto) # new_order.insert(0, cproto) # else: ## current_order = [] # for contact in clist: # cproto, cdata = contact.split('://') # cdict[cproto] = contact # current_order.append(cproto) # new_index = -1 # if cproto in new_order: # new_index = new_order.index(cproto) # old_index = -1 # if cproto in current_order: # old_index = current_order.index(cproto) # if new_index < 0: # new_order.insert(0, cproto) # else: # if old_index < new_index: # new_order.remove(cproto) # new_order.insert(0, cproto) # else: # new_order.remove(cproto) # new_order.append(cproto) # new_contacts.update(cdict) lg.out(4, ' new contacts: %s' % str(new_contacts)) lg.out(4, ' new order: %s' % str(new_order_correct)) # new_list = [] # for nproto in new_order_correct: # new_list.append(new_contacts[nproto]) return new_contacts, new_order_correct
def _push(self): from transport import gateway if self.route: # if this packet is routed - send directly to route host gateway.send_file( strng.to_bin(self.route['remoteid']), strng.to_text(self.route['proto']), strng.to_bin(self.route['host']), self.filename, self.description, self, ) self.items.append( WorkItem(strng.to_text(self.route['proto']), strng.to_bin(self.route['host']), self.filesize)) self.automat('items-sent') return # get info about his local IP localIP = identitycache.GetLocalIP(self.remote_idurl) workitem_sent = False if self.wide: # send to all his contacts for contactmethod in self.remote_identity.getContacts(): proto, host = nameurl.IdContactSplit(contactmethod) if host.strip() and \ settings.transportIsEnabled(proto) and \ settings.transportSendingIsEnabled(proto) and \ gateway.can_send(proto) and \ gateway.is_installed(proto): if proto == 'tcp' and localIP: host = localIP gateway.send_file( strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self, ) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) workitem_sent = True if not workitem_sent: self.automat('nothing-to-send') lg.warn('(wide) no supported protocols with %s' % self.remote_idurl) else: self.automat('items-sent') return # send to one of his contacts, # now need to decide which transport to use # let's prepare his contacts first byproto = self.remote_identity.getContactsByProto() tcp_contact = None if settings.enableTCP() and settings.enableTCPsending(): tcp_contact = byproto.get('tcp', None) udp_contact = None if settings.enableUDP() and settings.enableUDPsending(): udp_contact = byproto.get('udp', None) http_contact = None if settings.enableHTTP() and settings.enableHTTPsending(): http_contact = byproto.get('http', None) proxy_contact = None if settings.enablePROXY() and settings.enablePROXYsending(): proxy_contact = byproto.get('proxy', None) working_protos = p2p_stats.peers_protos().get(self.remote_idurl, set()) # tcp seems to be the most stable proto # now let's check if we know his local IP and # he enabled tcp in his settings to be able to receive packets from others # try to send to his local IP first, not external if tcp_contact and localIP: if gateway.is_installed('tcp') and gateway.can_send(proto): proto, host, port, fn = nameurl.UrlParse(tcp_contact) if port: host = localIP + ':' + str(port) gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return # tcp is the best proto - if it is working - this is the best case!!! if tcp_contact and 'tcp' in working_protos: proto, host, port, fn = nameurl.UrlParse(tcp_contact) if host.strip() and gateway.is_installed( proto) and gateway.can_send(proto): if port: host = host + ':' + str(port) gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return # udp contact if udp_contact and 'udp' in working_protos: proto, host = nameurl.IdContactSplit(udp_contact) if host.strip() and gateway.is_installed( 'udp') and gateway.can_send(proto): gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return # http contact if http_contact and 'http' in working_protos: proto, host, port, _ = nameurl.UrlParse(http_contact) if host.strip() and gateway.is_installed( proto) and gateway.can_send(proto): if port: host = host + ':' + str(port) gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return # proxy contact - he may use other node to receive and send packets if proxy_contact and 'proxy' in working_protos: proto, host = nameurl.IdContactSplit(proxy_contact) if host.strip() and gateway.is_installed( 'proxy') and gateway.can_send(proto): gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return # finally use the first proto we supported if we can not find the best preferable method for contactmethod in self.remote_identity.getContacts(): proto, host, port, fn = nameurl.UrlParse(contactmethod) if port: host = host + ':' + str(port) # if method exist but empty - don't use it if host.strip(): # try sending with tcp even if it is switched off in the settings if gateway.is_installed(proto) and gateway.can_send(proto): if settings.enableTransport( proto) and settings.transportSendingIsEnabled( proto): gateway.send_file(strng.to_bin(self.remote_idurl), strng.to_text(proto), strng.to_bin(host), self.filename, self.description, self) self.items.append( WorkItem(strng.to_text(proto), strng.to_bin(host), self.filesize)) self.automat('items-sent') return self.automat('nothing-to-send') lg.warn('no supported protocols with %s : %s %s %s, byproto:%s' % (self.remote_idurl, tcp_contact, udp_contact, working_protos, str(byproto)))
def enabled(self): from main import settings if settings.transportIsEnabled('proxy'): return False return settings.enableProxyServer()
def _check_to_use_best_proto(self): # if no incoming traffic - do nothing if len(active_protos()) == 0: return True lid = my_id.getLocalIdentity() order = lid.getProtoOrder() # if no protocols in local identity - do nothing if len(order) == 0: return True # when transport proxy is working we do not need to check our contacts at all if settings.transportIsEnabled('proxy'): if driver.is_on('service_proxy_transport'): if settings.transportReceivingIsEnabled('proxy'): try: # TODO: change here to receive the value directly from service_proxy_transport object router_idurl = driver.services( )['service_proxy_transport'].transport.options[ 'router_idurl'] except: router_idurl = None if router_idurl: router_identity = identitycache.FromCache(router_idurl) contacts_is_ok = True router_protos = router_identity.getContactsByProto() if lid.getContactsNumber() != len(router_protos): contacts_is_ok = False if contacts_is_ok: for proto, contact in router_protos.items(): if lid.getProtoContact(proto) != contact: contacts_is_ok = False if contacts_is_ok: if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto returning True : proxy_transport is OK' ) return True first = order[0] # if first contact in local identity is not working yet # but there is another working methods - switch first method if first not in active_protos(): if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto first contact (%s) is not working! active_protos()=%s' % (first, str(active_protos()))) return False # #small hack to make udp as first method if all is fine # if first != 'udp' and ('udp' in active_protos() and 'tcp' in active_protos()): # lg.out(2, 'p2p_connector._check_to_use_best_proto first contact (%s) but UDP also works! active_protos()=%s' % (first, str(active_protos()))) # return False # if tcp contact is on first place and it is working - we are VERY HAPPY! - no need to change anything - return False if first == 'tcp' and 'tcp' in active_protos(): return True # but if tcp method is not the first and it works - we want to TURN IT ON! - return True if first != 'tcp' and 'tcp' in active_protos(): if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto tcp is not first but it works active_protos()=%s' % str(active_protos())) return False # if we are using udp and it is working - this is fantastic! if first == 'udp' and 'udp' in active_protos(): # but let's check if TCP is also working # in that case we want to switch to TCP if 'tcp' in active_protos(): return False return True # udp seems to be working and first contact is not working - so switch to udp if first != 'udp' and 'udp' in active_protos(): if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto udp is not first but it works active_protos()=%s' % str(active_protos())) return False # http seems to work and it is first - cool! if first == 'http' and 'http' in active_protos(): return True # but if http method is not the first and it works - we want to TURN IT ON! - return True if first != 'http' and 'http' in active_protos(): if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto http is not first but it works active_protos()=%s' % str(active_protos())) return False # if we are using proxy and it is working - that is fine - it must work always! if first == 'proxy' and 'proxy' in active_protos(): return True # proxy seems to be working and first contact is not working - so switch to proxy if first != 'proxy' and 'proxy' in active_protos(): if _Debug: lg.out( _DebugLevel - 6, 'p2p_connector._check_to_use_best_proto proxy is not first but it works active_protos()=%s' % str(active_protos())) return False # in other cases - do nothing return True
def buildProtoContacts(id_obj, skip_transports=[]): """ Create a full list of needed transport methods to be able to accept incoming traffic from other nodes. Make calls to transport services to build a list of my contacts. """ from services import driver # prepare contacts current_contats = id_obj.getContactsByProto() current_order = id_obj.getProtoOrder() if _Debug: lg.out(_DebugLevel, 'my_id.buildProtoContacts') lg.out(_DebugLevel, ' current contacts: %s' % str(current_contats)) lg.out(_DebugLevel, ' current order: %s' % str(current_order)) new_contacts = {} new_order_correct = [] # prepare list of active transports active_transports = [] for proto in getValidTransports(): if proto in skip_transports: continue if not settings.transportIsEnabled(proto): continue if not settings.transportReceivingIsEnabled(proto): continue if not driver.is_on('service_%s_transport' % proto): lg.warn('transport "%s" is enabled, but service_%s_transport() is not ready yet' % (proto, proto)) continue active_transports.append(proto) # sort active transports by priority if _Debug: lg.out(_DebugLevel, ' active transports: %s' % str(active_transports)) active_transports.sort(key=settings.getTransportPriority) if _Debug: lg.out(_DebugLevel, ' sorted transports: %s' % str(active_transports)) if not driver.is_on('service_gateway'): new_contacts = current_contats new_order_correct = current_order lg.warn('service_gateway() is not started, use my current contacts as a source') else: from transport import gateway # build contacts data according transports priorities new_order = current_order for proto in active_transports: clist = gateway.transport(proto).interface.build_contacts(id_obj) cdict = {} corder = [] for contact in clist: cproto, _ = contact.split(b'://') cdict[cproto] = contact corder.append(cproto) new_contacts.update(cdict) for cproto in corder: if cproto not in new_order: new_order.append(cproto) new_order_correct = list(new_order) for nproto in new_order: if nproto not in list(new_contacts.keys()): new_order_correct.remove(nproto) if _Debug: lg.out(_DebugLevel, ' new contacts: %s' % str(new_contacts)) lg.out(_DebugLevel, ' new order: %s' % str(new_order_correct)) return new_contacts, new_order_correct
def _push(self): if self.route: # if this packet is routed - send directly to route host gateway.send_file( self.route["remoteid"], self.route["proto"], self.route["host"], self.filename, self.description ) self.items.append(WorkItem(self.route["proto"], self.route["host"], self.filesize)) self.automat("items-sent") return # get info about his local IP localIP = identitycache.GetLocalIP(self.remote_idurl) workitem_sent = False if self.wide: # send to all his contacts for contactmethod in self.remote_identity.getContacts(): proto, host = nameurl.IdContactSplit(contactmethod) if ( host.strip() and settings.transportIsEnabled(proto) and settings.transportSendingIsEnabled(proto) and gateway.can_send(proto) and gateway.is_installed(proto) ): if proto == "tcp" and localIP: host = localIP gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) workitem_sent = True if not workitem_sent: self.automat("nothing-to-send") lg.warn("(wide) no supported protocols with %s" % self.remote_idurl) else: self.automat("items-sent") return # send to one of his contacts, # now need to decide which transport to use # let's prepare his contacts first byproto = self.remote_identity.getContactsByProto() tcp_contact = None if settings.enableTCP() and settings.enableTCPsending(): tcp_contact = byproto.get("tcp", None) udp_contact = None if settings.enableUDP() and settings.enableUDPsending(): udp_contact = byproto.get("udp", None) proxy_contact = None if settings.enablePROXY() and settings.enablePROXYsending(): proxy_contact = byproto.get("proxy", None) working_protos = stats.peers_protos().get(self.remote_idurl, set()) # tcp seems to be the most stable proto # now let's check if we know his local IP and # he enabled tcp in his settings to be able to receive packets from others # try to send to his local IP first, not external if tcp_contact and localIP: if gateway.is_installed("tcp") and gateway.can_send(proto): proto, host, port, fn = nameurl.UrlParse(tcp_contact) if port: host = localIP + ":" + str(port) gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) self.automat("items-sent") return # tcp is the best proto - if it is working - this is the best case!!! if tcp_contact and "tcp" in working_protos: proto, host, port, fn = nameurl.UrlParse(tcp_contact) if host.strip() and gateway.is_installed(proto) and gateway.can_send(proto): if port: host = host + ":" + str(port) gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) self.automat("items-sent") return # udp contact if udp_contact and "udp" in working_protos: proto, host = nameurl.IdContactSplit(udp_contact) if host.strip() and gateway.is_installed("udp") and gateway.can_send(proto): gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) self.automat("items-sent") return # proxy contact - he may use other node to receive and send packets if proxy_contact and "proxy" in working_protos: proto, host = nameurl.IdContactSplit(proxy_contact) if host.strip() and gateway.is_installed("proxy") and gateway.can_send(proto): gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) self.automat("items-sent") return # finally use the first proto we supported if we can not find the best preferable method for contactmethod in self.remote_identity.getContacts(): proto, host, port, fn = nameurl.UrlParse(contactmethod) if port: host = host + ":" + str(port) # if method exist but empty - don't use it if host.strip(): # try sending with tcp even if it is switched off in the settings if gateway.is_installed(proto) and gateway.can_send(proto): if settings.enableTransport(proto) and settings.transportSendingIsEnabled(proto): gateway.send_file(self.remote_idurl, proto, host, self.filename, self.description) self.items.append(WorkItem(proto, host, self.filesize)) self.automat("items-sent") return self.automat("nothing-to-send") lg.warn( "no supported protocols with %s : %s %s %s, byproto:%s" % (self.remote_idurl, tcp_contact, udp_contact, working_protos, str(byproto)) )