305 lines
10 KiB
C
305 lines
10 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* P2 - MI amb sockets TCP/IP - Part II */
|
|
/* Fitxer nodelumi.c que implementa la interfície aplicació-administrador */
|
|
/* d'un node de LUMI, sobre la capa d'aplicació de LUMI (fent crides a la */
|
|
/* interfície de la capa LUMI -fitxers lumi.c i lumi.h-). */
|
|
/* */
|
|
/* Autors: Marc Cané Salamià, Enric Rodríguez Galán */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
/* Inclusió de llibreries, p.e. #include <stdio.h> o #include "meu.h" */
|
|
/* Incloem "MIp2-lumi.h" per poder fer crides a la interfície de LUMI */
|
|
#include "MIp2-lumi.h"
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* Definició de constants, p.e., #define MAX_LINIA 150 */
|
|
|
|
struct usuari{
|
|
char nom[MAX_USER_NICK];
|
|
char IP[IP_LENGTH];
|
|
int UDP_port;
|
|
};
|
|
|
|
int ObrirFitxLectura(const char *NomFitx)
|
|
{
|
|
int filedesc = open(NomFitx, O_RDONLY);
|
|
if (filedesc < 0){
|
|
LUMI_MostraError("Error al obrir el fitxer de configuracio");
|
|
return -1;
|
|
}
|
|
return filedesc;
|
|
}
|
|
|
|
//Pre: buff apunta a un buffer del màxim de caràcters que pot tenir una línia
|
|
//Post: retorna 1 si no s'ha arribat a la marca de fi de fitxer, 0 altrament
|
|
int LlegirLinia(int fitxer, char * buff){
|
|
char c=0;
|
|
int byte_llegit=1, i=0;
|
|
|
|
while(byte_llegit!=0 && c!='\n'){
|
|
byte_llegit=read(fitxer,&c,1);
|
|
buff[i]=c;
|
|
i++;
|
|
}
|
|
buff[i-1]='\0';
|
|
return byte_llegit;
|
|
}
|
|
|
|
char DOMINI[MAX_LEN_DOMINI];
|
|
|
|
void InicialitzarTaulaUsuaris(struct usuari ** taula_usuaris, int n){
|
|
*taula_usuaris = (struct usuari *) malloc(sizeof(struct usuari)*n);
|
|
}
|
|
|
|
int CercarUsuariPerNom(struct usuari * taula_usuaris, const char * NomUsuari, int n_usuaris){
|
|
/*int trobat = 0, mig, esq=0 , dret = n_usuaris-1 , comparacio;
|
|
while(trobat == 0 && esq<=dret){
|
|
mig = (dret + esq) / 2;
|
|
comparacio = strcmp(taula_usuaris[mig].nom, NomUsuari);
|
|
if (comparacio == 0) trobat = 1;
|
|
else{
|
|
if (comparacio < 0) esq=mig+1;
|
|
else dret=mig-1;
|
|
}
|
|
}
|
|
if (trobat == 1) return mig;
|
|
else return (-1)*mig;*/
|
|
int i=0, trobat=0;
|
|
while(i<n_usuaris && !trobat){
|
|
if(strcmp(taula_usuaris[i].nom, NomUsuari)==0)
|
|
trobat=1;
|
|
else i++;
|
|
}
|
|
return trobat?i:-1*i;
|
|
}
|
|
|
|
int CercarUsuariPerIPiPort(struct usuari * taula_usuaris, const char * IP, int port, int n_usuaris){
|
|
int trobat = 0, i = 0;
|
|
while (i<n_usuaris && !trobat) {
|
|
if ((strcmp(taula_usuaris[i].IP, IP) == 0) && (taula_usuaris[i].UDP_port == port)) trobat = 1;
|
|
else i++;
|
|
}
|
|
return trobat?i:-1*i;
|
|
}
|
|
|
|
void intercanviar(struct usuari * taula_usuaris, int i, int j){
|
|
struct usuari aux = taula_usuaris[i];
|
|
taula_usuaris[i] = taula_usuaris[j];
|
|
taula_usuaris[j] = aux;
|
|
}
|
|
//n _usuaris < max_usuaris sempre
|
|
int DonardAltaUsuari(struct usuari * taula_usuaris, const char * NomUsuari, int n_usuaris, int max_usuaris){
|
|
|
|
if (n_usuaris == max_usuaris) return -1;
|
|
|
|
int posicio = CercarUsuariPerNom(taula_usuaris, NomUsuari, n_usuaris);
|
|
if (posicio > 0) {
|
|
//LUMI_MostraError("Error: l'usuari %s ja esta donat d'alta", NomUsuari);
|
|
return -1;
|
|
}
|
|
else{
|
|
/*int i;
|
|
posicio*=-1;
|
|
for(i = n_usuaris-1; i>posicio; i--) intercanviar(taula_usuaris,i,i-1); //potser aixo peta*/
|
|
posicio = n_usuaris;
|
|
strcpy(taula_usuaris[posicio].nom, NomUsuari);
|
|
taula_usuaris[posicio].UDP_port=-1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LlegirTaulaDesdeFitxer(const char * file_name, struct usuari ** taula_usuaris){
|
|
int fitxer = ObrirFitxLectura(file_name);
|
|
if (fitxer == -1) return -1;
|
|
|
|
char buff[100];
|
|
int byte_llegit, total_usuaris=0, alta_usuaris=0;
|
|
|
|
LlegirLinia(fitxer,buff); //llegim el nom del domini
|
|
strcpy(DOMINI,buff);
|
|
|
|
LlegirLinia(fitxer,buff); //llegim el nombre d'usuaris del domini
|
|
total_usuaris=atoi(buff);
|
|
|
|
InicialitzarTaulaUsuaris(taula_usuaris, total_usuaris);
|
|
|
|
byte_llegit = LlegirLinia(fitxer,buff); //legir primer usuari
|
|
//printf("%i", (*taula_usuaris)[0].UDP_port);
|
|
|
|
while(byte_llegit!=0 && alta_usuaris<total_usuaris){
|
|
if ( DonardAltaUsuari(*taula_usuaris,buff,alta_usuaris,total_usuaris) == -1){
|
|
//error l'usuari ja exisita, s'ha de ficar al fitxer log
|
|
} else alta_usuaris++;
|
|
byte_llegit = LlegirLinia(fitxer,buff);
|
|
}
|
|
|
|
return alta_usuaris;
|
|
}
|
|
|
|
int desregistrarUsuari(struct usuari * taula_usuaris, int usuari){
|
|
taula_usuaris[usuari].UDP_port = -1;
|
|
return 0;
|
|
}
|
|
|
|
int registrarUsuari(struct usuari * taula_usuaris, int usuari, const char * IP, int portUDP){
|
|
strcpy(taula_usuaris[usuari].IP,IP);
|
|
taula_usuaris[usuari].UDP_port = portUDP;
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc,char *argv[])
|
|
{
|
|
/* Declaració de variables, p.e., int n; */
|
|
int fi_execucio = 0, user, n_usuaris, portUDPrem, bytes_rebuts, Sck=0, canal;
|
|
struct usuari * taula_usuaris = NULL;
|
|
char buffer[MAX_MISSATGE_PLUMI+1], tipus_missatge, IPrem[IP_LENGTH], adr_preguntador[MAX_USER_NICK+MAX_LEN_DOMINI+2];
|
|
char nickname[MAX_USER_NICK], domini_usuari[MAX_LEN_DOMINI], fitxer_log[MAX_NOM_FITXER];
|
|
char buffer2[300];
|
|
/* Expressions, estructures de control, crides a funcions, etc. */
|
|
|
|
printf("Estic al pas 1\n");
|
|
|
|
if ((n_usuaris = LlegirTaulaDesdeFitxer("/home/markus/ClionProjects/nodelumi2/MIp2-nodelumi.cfg"/*NOM_FITXER_CONFIG*/, &taula_usuaris)) == -1 ){
|
|
//LUMI_EscriureFitxerLog(NOM_FITXER_LOG, "Error al llegir el fitxer de configuracio");
|
|
//Apagar tots
|
|
return -1;
|
|
}
|
|
|
|
//Falta encapsular
|
|
|
|
printf("Estic al pas 2\n");
|
|
|
|
//LUMI_ResolNomFitxerLog('N', fitxer_log, DOMINI);
|
|
strcpy(fitxer_log, "temporal.log");
|
|
Sck = LUMI_InicialitzarNode(fitxer_log);
|
|
|
|
int llistaSck[] = {Sck};
|
|
|
|
canal = HaArribatAlgunaCosaEnTemps(llistaSck, 1, 0);
|
|
|
|
printf("Estic al pas 3");
|
|
|
|
bytes_rebuts = LUMI_RepLiniaDe(Sck,IPrem,&portUDPrem, buffer, sizeof(buffer)); //encarregat d'enviar el AI si el format es erroni
|
|
|
|
while(fi_execucio!=1){
|
|
|
|
if (bytes_rebuts <= 0){ //si hi ha hagut error
|
|
if(bytes_rebuts == -1){ //si s'ha produit un error inesperat
|
|
close(Sck);
|
|
return 1;
|
|
}
|
|
else if (bytes_rebuts == 0) return 1; //si s'ha tancat el socket
|
|
//si bytes_rebuts == -2 només volem omitir la linia rebuda, aixi que no fem res
|
|
}
|
|
else{
|
|
buffer[bytes_rebuts] = '\0';
|
|
tipus_missatge = buffer[0];
|
|
LUMI_DescodificarMissatge(tipus_missatge, buffer, adr_preguntador, domini_usuari, nickname);
|
|
switch(tipus_missatge){
|
|
case 'R':
|
|
printf("nick=%s\n",nickname);
|
|
if (strcmp(DOMINI,domini_usuari) != 0) { //no es del nostre domini
|
|
LUMI_EnviaResposta(Sck, 'N', adr_preguntador, IPrem, portUDPrem);
|
|
} else{ //L'usuari a registrar es del nostre domini
|
|
user = CercarUsuariPerNom(taula_usuaris, nickname, n_usuaris);
|
|
if (user < 0){//L'usuari no esta a la taula
|
|
LUMI_EnviaResposta(Sck, 'N', NULL, IPrem, portUDPrem);
|
|
}
|
|
else //L'usuari existeix dins la taula
|
|
{
|
|
if(taula_usuaris[user].UDP_port!=-1) { //evitem suplantació d'identitat
|
|
registrarUsuari(taula_usuaris, user, IPrem, portUDPrem);
|
|
sprintf(buffer2, "L'usuari %s amb IP %s i portUDP %i s'ha registrar correctament", taula_usuaris[user].nom, taula_usuaris[user].IP, taula_usuaris[user].UDP_port);
|
|
printf("%s\n", buffer2);
|
|
LUMI_EnviaResposta(Sck, 'K', NULL, IPrem, portUDPrem);
|
|
}
|
|
else{
|
|
LUMI_EnviaResposta(Sck,'O',adr_preguntador,IPrem,portUDPrem);
|
|
printf("No s'ha pogut registrar l'usuari %s, ja estava registrat\n", nickname);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 'D':
|
|
user = CercarUsuariPerIPiPort(taula_usuaris,IPrem, portUDPrem, n_usuaris);
|
|
if (user < 0){//L'usuari no esta a la taula
|
|
LUMI_EnviaResposta(Sck, 'N', NULL, IPrem, portUDPrem);
|
|
}
|
|
else //L'usuari existeix dins la taula
|
|
{
|
|
desregistrarUsuari(taula_usuaris, user);
|
|
sprintf(buffer2, "L'usuari %s amb IP %s s'ha desregistrat correctament", taula_usuaris[user].nom, taula_usuaris[user].IP, taula_usuaris[user].UDP_port);
|
|
printf("%s\n",buffer2);
|
|
LUMI_EnviaResposta(Sck, 'K', NULL, IPrem, portUDPrem);
|
|
}
|
|
break;
|
|
case 'L': //Aqui els buffers domini i nickname contenen la informació de l'usuari que es vol localitzar.
|
|
|
|
if(strcmp(domini_usuari, DOMINI) == 0)
|
|
{
|
|
sprintf(buffer2, "L'usuari %s intenta localitzar a algu", adr_preguntador);
|
|
printf("%s\n",buffer2);
|
|
user = CercarUsuariPerNom(taula_usuaris, nickname, n_usuaris); //farà referencia al usuari que es vol localitzar
|
|
if (user < 0) {
|
|
LUMI_EnviaResposta(Sck, 'N', adr_preguntador, IPrem, portUDPrem);
|
|
}
|
|
else if (taula_usuaris[user].UDP_port == -1){
|
|
LUMI_EnviaResposta(Sck, 'O', adr_preguntador, IPrem, portUDPrem); ///AIXO NO HA DE PORTAR ADR PREGUNTADOR
|
|
}
|
|
else{
|
|
LUMI_EnviaPeticioServeiLocalitzacio(Sck, adr_preguntador, taula_usuaris[user].IP, taula_usuaris[user].UDP_port);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ResolDNSaIP(domini_usuari, IPrem) < 0)
|
|
LUMI_MostraError("Error al resoldre direccio dns");
|
|
else {
|
|
LUMI_EnviaLiniaA(Sck, IPrem, UDP_PORT, buffer); //sense retransmissions
|
|
}
|
|
}
|
|
break;
|
|
case 'C':
|
|
case 'A': //En ambdos casos s'actua de la mateixa manera
|
|
if(strcmp(domini_usuari, DOMINI) == 0){
|
|
user = CercarUsuariPerNom(taula_usuaris, nickname, n_usuaris);
|
|
if (user >= 0){
|
|
strcpy(IPrem,taula_usuaris[user].IP);
|
|
portUDPrem = taula_usuaris[user].UDP_port;
|
|
LUMI_EnviaLiniaA(Sck, IPrem, portUDPrem, buffer); //sense retransmissions
|
|
}
|
|
else {
|
|
LUMI_MostraError("Problema al reenviar una peticio: L'usuari no existeix");
|
|
}
|
|
}
|
|
else{
|
|
if (ResolDNSaIP(domini_usuari, IPrem) < 0)
|
|
LUMI_MostraError("Error al resoldre direccio dns");
|
|
else {
|
|
LUMI_EnviaLiniaA(Sck, IPrem, UDP_PORT, buffer); //sense retransmissions
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
//Error en el format
|
|
break;
|
|
}
|
|
}
|
|
|
|
canal = HaArribatAlgunaCosaEnTemps(llistaSck, 1, 0);
|
|
|
|
bytes_rebuts = LUMI_RepLiniaDe(Sck,IPrem,&portUDPrem, buffer, sizeof(buffer)); //encarregat d'enviar el AI si el format es erroni
|
|
}
|
|
|
|
close(Sck);
|
|
return 0;
|
|
}
|