Server

Antonio D'Errico 2148054262

 

 

Corso di Reti di Calcolatori
Prof. Antonio Corradi
Università di Bologna Facoltà di Ingegneria

 

 


Progetto del Server per una Chat Aziendale
2 - Analisi dei requisiti e specifica del progetto



I-Architettura del sistema

 

  Il sistema è stato modellato secondo il pattern Client/Server. Questa parte del progetto si occupa della realizzazione della parte Server del sistema da interfacciare con il client ChatD.

L’idea che sta alla base del progetto è quella che un client possa connettersi ad uno qualsiasi dei server che realizzano la chat conoscendone solo l’indirizzo e la porta d’ascolto; una volta connesso il client dovrà identificarsi e così potrà iniziare ad utilizzare la Chat.

 

 

I server, da parte loro, sono tutti interconnessi gli uni agli altri in modo da formare una rete nella quale nessun server è predominante rispetto agli altri e tutti condividono le stesse informazioni sui gruppi e i client ad essi collegati, in questo modo si semplifica il protocollo di comunicazione a scapito però di un overhead nelle connessioni in quanto ogni server è collegato a tutti quelli che compongono la rete. Inoltre poiché le discussioni sono organizzate secondo gruppi tematici il server deve gestire tutte le operazioni che dei vari client possono compiere come:

 

-         inviare messaggi all’interno del gruppo,

-         l’aggiunta di un gruppo,

-         liste di utenti collegati,

-         cambiamento di gruppo,

-         ecc.

Si è scelto di non implementare un vero e proprio protocollo di autenticazione in quanto sarebbe stato necessario l’intervento di una terza entità che avrebbe dovuto autenticare chi richiede di accedere al servizio, o che, nel caso di un server, richiede di entrare a far parte della rete di interconnessione. Comunque la fase di autenticazione è presente nel protocollo ed implementata in modo lasco, così che l’estensione di questo possa essere effettuata in modo indolore.

 

 

Cuore del progetto è il file StdProtocol che incapsula il protocollo di comunicazione gestisce le informazioni relative ai gruppi ed ai clienti connessi smista i messaggi.

Poiché il server deve rimanere in attesa di due tipi di connessione ho creato due thread che si mettono in attesa rispettivamente di altri server e altri client e sono ListenServer e ListenClient, che rimangono in attesa bloccandosi di una connessione e quando la ottengono generano rispettivamente dei thread di tipo ComServer e ComClient che gestiscono i messaggi e si occupano di ottenere dall’oggetto StdProtocol le informazioni che i sistemi remoti richiedono.




II-Protocollo Client

 

 Compito del server è quello di rimanere in attesa di nuove connessioni e gestire i le azioni dei client collegati e rimanere in contatto se esistono con altri server.

Fase fondamentale, è svolta dal thread ListenClient, che si occupa di, rimanere in attesa sulla porta predisposta all’ascolto dei client e generare il thread ComClient che gestisce la socket, elabora parzialmente i messaggi che riceve, invocando le corrette procedure che fanno parte del protocollo di comunicazione stabilito e raccoglie le informazioni sul client.

La prima fase di comunicazione consiste nell’autenticazione e prevede l’invio dell’username e della password da parte dell’utente, dovrebbe seguire un controllo da parte del server (non implementato) che, in caso di esito positivo, rende possibile al client di connettersi alla Chat.

Il client appena connesso entra nel gruppo default che è sempre presente su tutti i server potrà poi se vuole cambiarlo. La scelta della connessione automatica ad un gruppo è stata dettata dal fatto che in questo modo al client non vengono fatti conoscere in anticipo (prima dell’autenticazione) tutti i gruppi presenti sul sistema anche se ciò ovviamente pone dei forti overhead nella gestione (al collegamento) del gruppo default.

 

 

Seguono poi i messaggi  di routine che permettono di cambiare gruppo, conoscere gli appartenenti ad un gruppo, i gruppi connessi, inviare messaggi e lasciare la chat in modo “soft”.

Le stringhe fornite dall’utente sono del tipo:

 

<Header><Messaggio>

 

Dove Header appartiene alla seguente lista di comandi validi:

 

USER

<username>, username dell’utente (fase di autenticazione)

PASS

<password>, password dell’utente (fase di autenticazione)

JOIN

<nome_gruppo>, l’utente richiede un cambio di gruppo

QUIT

L’utente abbandona in modo soft la chat

MSG

<messaggio>, invio al gruppo del messaggio

LISTUSERS

Richiesta lista utenti di quel gruppo

LISTGROUPS

Richiesta lista di tutti i gruppi

ERROR

Errore generico segnalato al client

 

Il server risponde poi a questi messaggi con i seguenti codici:

 

201: Ok con inserimento al gruppo;

202: Ok con rimozione dal gruppo;

203: Ok login effettuato;

241: Ok messaggio pubblico consegnato;

242: Ok messaggio privato consegnato;

310: Successo parziale nel login;

430: Fail, fase di autenticazione;

441: Fail, errore nella consegna del messaggio pubblico;

442: Fail, errore nella consegna del messaggio privato;

610: Risposta al comando LISTGROUPS;

611: Messaggio automatico di refresh della users window;

612: Messaggio automatico di refresh della groups window;

632: Risposta al comando LISTUSERS;

641: Messaggio pubblico da un utente del gruppo;

642: Messaggio privato da un utente del gruppo;

 

Di questi messaggi di risposta alcuni hanno un formato più complesso in quanto riportano delle rappresentazioni di strutture dati che devono essere fornite all’utente tali messaggi sono:

 

Cod. Messaggio

Formato

610

<Group_name_1> <Group_name_2>

 ...

<Group_name_n>

611

<User_name>:<IP_address>:<Port>

<User_name>:<IP_address>:<Port> 

612

<Group_name_1> <Group_name_2>

 ...

<Group_name_n>

632

<User_name>:<IP_address>:<Port>

<User_name>:<IP_address>:<Port>

 

Il formato di risposta è fondamentalmente lo stesso per 610/612 e 611/632 ma cambia ovviamente il modo di elaborazione da parte del client in quanto risponde messaggi differenti.

 

Se il client, cessa di esistere o invia il messaggio di QUIT, è automaticamente rimosso da tutte le strutture dati che il server gestisce ed è considerato disconnesso, tutti i client del gruppo di appartenenza del client rimosso, ricevono la lista nuova utenti.

Per non appesantire il sistema non si è andato ne’ a creare un log file nel quale registrare tutte le operazioni effettuate e ovviamente non si controlla chi è o meno connesso in quanto ciò rientra nei “compiti”

della fase di autenticazione.




III-Protocollo Server

 

Il server deve rimanere in attesa sia di altri clients sia di altri server in modo che si possa formare la rete per la comunicazione, in teoria un solo server può, dal punto di vista del protocollo, gestire da solo tutti i dati e i clients connessi, ciò ovviamente non è possibile nel mondo reale a causa delle risorse “limitate” che sono presenti sul sistema e quindi per un corretto bilanciamento del carico il protocollo prevede più server che si devono coordinare in modo da mantenere coerenti tutte le informazioni per gestire i clients.

Non esiste un server principale ma le informazioni sono distribuite su tutti gli appartenenti alla rete e solo una piccola parte replicata su ognuno in questo modo se un server cessa di funzionare i clients ad esso connessi non sono più visti dagli altri e i server semplicemente cancellano tutte le informazioni a lui relative non preoccupandosi di altro.

 

Anche il protocollo di login presso un altro server è abbastanza semplice, quando il server parte gli vengono fornite le porte di ascolto per i client e per i server l’username e la password, il server crea se possibile le proprie socket e poi legge un file di configurazione dove sono presenti gli IP address e le relative porte di ascolto di altri server noti (tale file potrebbe essere ad ogni sessione aggiornato!) e tenta di connettersi ad essi.

Se non trova nessuno in ascolto agli indirizzi noti crea una nuova rete e si mette in ascolto di altri server e client.

Nel caso trovi qualcuno in ascolto, si registra presso questo server (anche qui la fase di autenticazione non è stata correttamente implementata in quanto avrebbe per forza richiesto la progettazione di una terza entità riconosciuta ai due che fungesse da arbitro), richiede gli indirizzi di tutti i server attivi in quel momento e si registra anche presso questi, richiede poi la lista dei gruppi attivi e dei relativi utenti connessi e si mette in attesa di connessioni da altri clients e server.

 

 

Nel caso due server cerchino di entrare a far parte contemporaneamente della rete potrebbero non vedersi con questo tipo di protocollo, una soluzione che si può inserire è quella che prevede uno scambio periodico di messaggi di refresh information in momenti stabiliti, essendo però l’attivazione di un server un’operazione poco frequente ho deciso di non inserire per adesso questo ulteriore tipo di controllo che avrebbe aggiunto un ulteriore overhead.

Il protocollo si basa, come già avveniva tra server e client, sullo scambio di messaggi che comportano richiesta di informazioni e servizi. Il formato di richiesta è sostanzialmente il medesimo usato e prevede un messaggio così composto:

<Header><Messaggio>

 

dove Header appartiene al seguente insieme di messaggi validi:

 

SERVUSER

<username>, username del server (fase di autenticazione)

 

SERVPASS

<password>, password del server (fase di autenticazione)

 

NWGROUP

<nome_gruppo>, è stato creato un nuovo gruppo

che viene aggiunto alla lista degli attivi

 

SRVLISTSERVERS

Richiesta della lista dei server attivi (fase di learnig iniziale)

 

MSG

<nome_gruppo>@messaggio>, invio al gruppo del messaggio

 

SRVQUIT

Abbandono soft del server

 

GRPVAR

Variazione della composizione di un gruppo

 

SRVERROR

Errore generico

 

 

SRVPORT4SRV

Fornisce al server che mi ha fatto entrare

nella rete la porta di ascolto per i server

 

SRVPORT4CLNT

Fornisce al server che mi ha fatto entrare

nella rete la porta di ascolto per i clients

 

SRVGRPRQST

Richiesta di tutti i gruppi e di tutti gli utenti

collegati (fase di learnig iniziale)

 

I messaggi di risposta sono i seguenti:

310: Autenticazione parziale, richiesta di invio password, viene fornito in piggybacking il nome del server al quale si è fatta la richiesta

203: Ok, autenticazione avvenuta con successo

632: Lista dei server connessi (fase di learning iniziale)

 

Il formato del messaggio di risposta 632 è il seguente:

632 <IP_address>:<listening_port> <IP_address>:<listening_port> ... <IP_address>:<listening_port>

è proprio da questo messaggio che segue la fase di autenticazione presso tutti i server e dopo essersi registrato presso gli altri server effetto la richiesta SRVGRPRQST alla quale mi viene risposto con una serie di NWGROUP GRPVAR che mi permettono di costruire il DataBase relativo ai client collegati.

 

 



IV-Funzionalita’ non implementate

 

Si è scelto di non implementare alcune funzionalità in quanto ne sarebbe risultato un progetto troppo complesso. Vediamone alcune in dettaglio dando alcune possibili tracce di soluzione.

La funzionalità forse più importante trascurata a livello di implementazione (ma non di progettazione) è quella che riguarda la questione sicurezza, non sono state fornite entità software che effettuino di fatto l’autenticazione  e si è preferito lasciare al solo protocollo (che ammette tutti) questo compito senza scrivere file di password e cose simili che il server avrebbe dovuto leggere e tenere aggiornato.

La soluzione che più sarebbe stata congeniale è quella che prevede un’entità che si occupa solo ed esclusivamente dell’autenticazione, strutturata a livelli o replicata (in modo da ridurre i tempi di ripresa del servizio in caso di fail), una sorta di server Kerberos, che fornisca password valide solo per quella sessione e gestica in modo automatico i tentativi di accesso multiplo.

Altra funzionalità non implementata è l’estensione dell’interfaccia grafica in modo da permettere una più facile ed intuitiva configurazione del server, un monitoraggio particolareggiato per ogni entità connessa e una migliore visualizzazione dei dati relativi alla situazione attuale.

Infine un’ulteriore miglioria potrebbe essere quella di raffinare il protocollo in modo che si forniscano più informazioni (ad es. versione client, versione sever, versione del protocollo, messaggi di configurazione…) e si possano permettere restrizioni sulla visibilità della rete.


 

Introduzione

Specifica requisiti

Specifica progetto

Java Doc

Sorgenti