Differences between revisions 6 and 7
Revision 6 as of 2009-05-21 16:05:55
Size: 4742
Editor: lukisi
Comment:
Revision 7 as of 2009-05-22 15:13:13
Size: 5530
Editor: lukisi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 54: Line 54:
Se è stata richiesta la verifica della condizione (tipo {{{|G'| < |G| and gnumb < |G|}}} ) questa viene eseguita con l'uso del '''coordinator node''' e i metodi going_in, going_out, going_out_ok. '''''TODO''': rimando al documento che approfondisce il coordinator node.'' In questa fase abbiamo bisogno dell'aiuto del '''coordinator node'''. '''''TODO''': rimando al documento che approfondisce il coordinator node.''
<<BR>>
Se stiamo creando un nodo di livello 0 ed è stata richiesta la verifica della condizione perché stiamo uscendo da un altro gnodo (tipo {{{|G'| < |G| and gnumb < |G|}}}) questa viene eseguita con l'uso del coordinator node e i metodi {{{going_out}}}, {{{going_in}}} che restituisce il nuovo IP convalidato, {{{going_out_ok}}} che conferma l'uscita.
<<BR>>
Se stiamo creando un gnodo di livello più alto questa condizione non serve. Va comunque richiesto il permesso al coordinator node di livello superiore (a meno che {{{we_are_alone}}}) con il metodo {{{going_in}}} che restituisce il nuovo IP convalidato.
<<BR>>
Se stiamo creando un gnodo di ultimo livello non viene fatto nessun controllo.
<<BR>>
'''''TODO''': A me pare che sia necessario anche in questo caso venire coadiuvati da un coordinator node globale. Ci sono controindicazioni a implementare un coordinator node a livello globale?''

La microfunc hook

La microfunc hook implementa la prima parte del meccanismo "communicating vessels" descritto nel documento topology.pdf.

I parametri che riceve, sono:
  (neigh_list=[], forbidden_neighs=[], condition=False, gnumb=0)

Quando viene richiamata?

  • Viene richiamata una prima volta all'avvio del demone (vedi fase di startup) solo per attivare le interfacce di rete. Di seguito, sempre nella fase di startup dopo aver eseguito una prima scansione della LAN con il radar, viene richiamata una seconda volta per fare il primo hook. Infatti un nodo appena avviato è subito un "hooking node". In queste chiamate non viene passato nessun argomento.

  • Viene richiamata come gestore dell'evento NET_COLLISION. Questo evento viene generato dalla classe Etp quando, durante l'esecuzione di un ETP ricevuto, si rileva una collisione di due reti disgiunte. In questo caso l'elenco neigh_list di vicini da esaminare è passato nell'evento ed è l'elenco dei nodi appartenenti all'altra rete. Infatti siamo nella rete più piccola e dobbiamo fare noi hook nella altra rete.

  • Viene richiamata nel metodo remotable communicating_vessels. Il metodo communicating_vessels può essere stato richiamato da remoto o da un evento ETP_EXECUTED locale. In ogni caso questo metodo eseguito localmente fa i suoi calcoli e poi richiama eventualmente hook, indicando i nodi con più spazi liberi del nostro e con gnumb=il numero di nodi liberi nel miglior candidato.

Cosa fa?

Si memorizza il proprio nip attuale in oldnip.
Deve scoprire se è solo. Per ora imposta we_are_alone = False.

Ricorda che la maproute.free_nodes_list(lvl) restituisce una lista dei posti liberi di livello lvl, tipo ad esempio [1, 2, 56, 57, 123, 124, 125, 200]
La funzione highest_free_nodes() restituisce una tupla (lvl, free_nodes_list) per il più alto livello in cui self.maproute.free_nodes_list(lvl) non è vuoto.
Quindi una cosa tipo (3, [1, 2, 56, 57, 123, 124, 125, 200])

Si inizia a preparare hfn che conterrà una lista di coppie (nip, highestfreenodes) partendo dal proprio attuale nip.
Quindi tipo [([44,33,22,11], (3, [1, 2, 56, 57, 123, 124, 125, 200])), ...]
Cioè
hfn = [ ( nip, ( lvl, [ id, id, id, ...] ) ), ( nip2, ( lvl2, [ id2, id2, id2, ...] ) ), ... ]
Per ora contiene il proprio nip e il livello più alto in cui la propria mappa ha qualche free_node

Se è stato specificato quali neighbour prendere in esame (caso collisione di due reti disgiunte) guarda solo quelli, sennò recupera tutti i neighbour conosciuti col metodo neigh_list della classe Neighbour.
Qui vediamo se siamo soli e valoriziamo we_are_alone.

Viene definita una funzione is_neigh_forbidden, per vedere se un neigh è incluso nell'elenco vietato forbidden_neighs.

Ogni neighbour passa al vaglio di is_neigh_forbidden. Inoltre ci si assicura di esaminare solo neighbour esterni. Per vedere se è del nostro stesso gnodo di livello 1 usiamo il metodo nip_cmp della classe Map, che restituirebbe 0.
Se passa queste verifiche si richiama su questo neighbour il metodo remotable highest_free_nodes e si aggiunge nip e lista nella hfn.

Dalla hfn cosi ottenuta si tolgono i livelli più bassi. Dall'elenco rimasto si prende la prima tupla con più nodi liberi, di questa il primo id di nodo libero.
Il caso estremo di "Netsukuku is full" viene rilevato qui.
Si genera il nuovo nip newnip, appartenente al (g)nodo libero trovato.
Se we_are_alone si genera anche un nuovo netid.

In questa fase abbiamo bisogno dell'aiuto del coordinator node. TODO: rimando al documento che approfondisce il coordinator node.
Se stiamo creando un nodo di livello 0 ed è stata richiesta la verifica della condizione perché stiamo uscendo da un altro gnodo (tipo |G'| < |G|   and  gnumb < |G|) questa viene eseguita con l'uso del coordinator node e i metodi going_out, going_in che restituisce il nuovo IP convalidato, going_out_ok che conferma l'uscita.
Se stiamo creando un gnodo di livello più alto questa condizione non serve. Va comunque richiesto il permesso al coordinator node di livello superiore (a meno che we_are_alone) con il metodo going_in che restituisce il nuovo IP convalidato.
Se stiamo creando un gnodo di ultimo livello non viene fatto nessun controllo.
TODO: A me pare che sia necessario anche in questo caso venire coadiuvati da un coordinator node globale. Ci sono controindicazioni a implementare un coordinator node a livello globale?

Per completare la fase di hook, si smette di rispondere ai radar.reply.
Si attiva il newnip nelle proprie interfacce di rete.
Si cambia il nip in me della mappa e si resettano i vari livelli della mappa.
Si esegue il metodo di Neighbour readvertise().
Si avvertono i nostri vicini chiamando il loro metodo remotable ip_change(oldip, newip)
Si riprende a rispondere al radar e si genera l'evento HOOKED.

Netsukuku/ita/MicrofuncHook (last edited 2009-05-25 22:28:57 by lukisi)