Where would you hide a tree?
Archiviato da olo2olo.uli.it
La cattiva sorte ha fatto in modo che il sottoscritto dovesse implementare questo “coso”. Lo chiamo coso perché non c’è una parola in una lingua moderna in grado di far sua la descrizione di questo mostro mitologico reincarnatosi software.
Questo coso nasce dall’esigenza di permettere la migrazione agevole delle linee xDSL in wholesale da Telecom Italia da operatore a operatore. Iniziativa lodevole di per sé, peccato che dall’idea alla realtà ci ha messo lo zampone Cthulhu ed è venuto fuori un obribrio che da solo giustificherebbe una Legge 194 col televoto.
Il protocollo è stato proposto da Telecom e infatti ricalca fedelmente tutte le limitazioni e le idiosincrasie dei loro sistemi legacy che più legacy non si può. Proprio così si progetta un protocollo: geniale!
A grandi linee deve funzionare così. L’utente ha un codice che identifica la propria linea (datogli dal suo provider ‘A’). L’utente va da un altro provider ‘B’, gli dà il codice, l’altro provider contatta A, gli dà il codice, A risponde che accetta, B effettua la migrazione.
Vediamo l’implementazione ‘alla Telecom’:
I server di telecom hanno un orario di apertura: Lun-Ven 8:00-19:00! Cara Telecom, se i tuoi sistemi sono così tarocchi da aver un “orario di apertura del servizio”, beh, è tua responsabilità prendere, accodare le richieste e processarle quando più ti pare. Ti sembra che io debba adeguarmi ai tuoi “orari di apertura” ?!? Per un servizio online? Pazzia. Semplice pazzia.
Ogni provider deve avere l’elenco degli altri provider con URI di contatto, codice operatore e certificato (?) dell’altro operatore.
Ci sono al momento 246 operatori. Inutile dire che mantenere 246 tabelle con 245 entries è un fallimento garantito. Il massimo che si è riusciti a fare è un foglio Excel con 50 colonne, indicazioni testuali, note, asteristi, URI specificate a cazzo e dati inconsistenti. Qualcuno si è inventato anche due URI diversi. CVD.
Viene usato XML over HTTP perché probabilmente qualcuno deve aver chiesto di usare delle tecnologie moderne, peccato che, come vedremo, ce li hanno infilati a forza :)
L’XML era privo di root element ma ora si sono accorti della cacchiata e hanno aggiunto i root element. Si chiamano xml1 e xml2, tanto per far capire la cura nella definizione dei formati.
I nomi degli elementi sono misti italiano, english,
minuscolo, MAIUSCOLO, CamelCase e CamelCAZZOMiPare, gli
elementi che possono apparire più volte sono chiamati
<pippo1%>, <pippo2%>, …, <pippoN%>, le date sono
in formato AAAA/MM/GG, ci sono elementi
Insomma, è evidente che lo schema XML è una semplice trasposizione dei loro record con campi a lunghezza fissa (che infatti viene allegato) e non è quello che chiunque conosca XML farebbe.
I messaggi XML sono trattati come file. Ogni file deve aver un nome in un formato particolare con i nomi degli operatori, la data e un numero progressivo. È addirittura ammesso rimandare lo stesso messaggio se il nome di file è lo stesso.
Non solo, il nome di file è presente sia nell’URI (come parametro), sia nel Content-disposition, che all’interno dell’XML. Evvai con la ridondanza. Idem per la data nel nome di file. Generatelo tu sto cazzo di nome se poi controlli se ti va bene!
Il POST HTTP viene fatto in multipart/form-data simulando il POST di una form con upload di file. Il nome di file è sia nel Content-disposition, sia nell’URI come parametro, sia all’interno di campo dell’XML.
Ah, dimenticavo, il nome del campo della form in cui viene mandato il file non è specificato quindi ciascuno ha usato il suo e nel server devo fare giochini strani per indovinarlo.
I codici di errore HTTP vengono ignorati mentre potrebbero essere il primo strato di gestione degli errori.
La descrizione è tutta in italiano con buona pace degli operatori stranieri.
Il protocollo prevede ritrasmissioni illimitate e senza timeout
Le “verifiche formali” sono differite, come se non fosse possibile effettuarle contestualmente al POST e rispondere immediatamente. Inoltre, se c’è un problema di comunicazione (certificati, uri, dolo) la risposta non arriva del tutto con migrazioni perse nel nulla.
Il codice migrazione non è opaco ed è guessable. Il codice di migrazione era formato dal codice operatore, il numero della linea da migrare (spesso uguale al numero di telefono del cliente), un non ben definito “codice servizio” e un codice di controllo.
Lasciamo pure stare il fatto che nella documentazione tutt’ora pubblicata la descrizione è sbagliata.
Il codice ha lunghezza variabile ma la parte variabile è in mezzo. Brutto assai eh?
Il codice contiene informazioni e questo lo rende poco flessibile ma questo è il meno. Essendo queste informazioni guessable un operatore poteva inventarsi il codice migrazione e migrare una linea all’insaputa dell’utente. Siamo in Italia e quindi è successo. Siamo in Italia e quindi invece di rompere il c…. a detto operatore abbiamo cambiato il protocollo. Peggiorandolo.
Ebbene, potevano aggiungere qualche carattere noto solo all’operatore donante e all’utente nel codice migrazione. Oppure potevano andare a sostituire tutte le altri informazioni che non sono realmente importanti, invce no, hanno deciso di usare la parte di “codice operatore” che è l’unica ad essere veramente importante perché dice chi contattare.
E usarlo come? Hanno fatto generare 200 codici random di tre lettere, da mandare via FAX a tutti gli altri operatori. Ovviamente con un basico calcolo delle probabilità ci si sarebbe resi conto che collisioni sarebbero state probabili. E infatti ci sono state.
Vabbé, risolte a mano le collisioni ora, oltre al tabellone da 250 operatori, ogni operatore deve anche tenersi 200 codici per ogni operatore, da usarsi per risalire all’operatore donante.
Le specifiche prevedono che il mittente debba validare l’XML con l’XSD. Ma in quale mondo è necessario? Se il mio programma non è bacato non potrà mai generare dell’XML non conforme. Se lo fa, al limite è responsabilità del destinatario lamentarsi forte.
Poi, qualche cretino ha pure deciso che è importante sapere l’IP del client, come se l’autenticazione TLS non fosse forte abbastanza. E via a comunicare e manutenere 250 indirizzi IP per 250 operatori.
E quando un povero sfigato deve rinumerare? Povero lui, perché deve comunicare a tutti gli operatori il nuovo indirizzo e nei giorni… mesi… anni che impiegheranno a riconfigurare i proprio sistemi quale IP usa il nostro client? Quello vecchio o quello nuovo? Tutti e due ovviamente, quindi bisogna mettere in piedi un sistema che permetta di usarli entrambi e bisogna aggiungere nel db anche un’informazione su quale indirizzo sorgente usare! E la rinumerazione? Beh, quella aspetta finché tutti gli operatori si saranno degnati di aggiornare i dati.
Come esercizio mentre ero seduto sulla tazza del WC (analogia di ispirazione) ho pensato a come avrebbe potuto essere pensato un protocollo alternativo.
Nei miei sogni fantasticavo che il codice di autorizzazione alla migrazione sarebbe potuto essere una stringa alfanumerica random (e magari senza ambiguità di O e 0) con appeso un dominio DNS univoca per ogni linea.
Una cosa tipo PD27PM15@uli.it
L’operatore recipient prende il dominio, fa un lookup SRV per _olo2olo._tcp.uli.it e tira fuori il nome e la porta di un server da contattare.
In seguito l’operatore recipient fa il suo bel POST https ad un’URI standard mandando un documento XML per ogni richiesta di migrazione e ottiene un documento XML in risposta con i dati tecnici della linea e un codice di autorizzazione. Oppure un bel 403, 400, 422 http se la richiesta ha problemi. Oppure un 503 se i suoi server sono fuori ufficio.
Ah, un GET ad un’altra URI ritorna un documento XML con i contatti “umani” dell’operatore. Incredibile cosa si può fare con l’informatica eh?
Risultato: Nessuna necessità di scambiarsi codice operatore, codici segreti, certificati, indirizzi IP, contatti tra ciascuno dei 250 operatori a ciascino dei 249 altri operatori.
Serve qualcos’altro? Boh… probabilmente sì… ma come risultato di una cagata mi pare già 10000000 volte meglio dell’aborto deforme prodotto dietro lautissimi compensi, suppongo, da chi sappiamo.