Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * C Implementation: nameServer
- *
- * Description:
- *
- *
- * Author: MCarmen de Toro <mc@mc>, (C) 2015
- *
- * Copyright: See COPYING file that comes with this distribution
- *
- */
- #include "nameServer.h"
- /* Reads a line ended with \n from the file pointer. */
- /* Return: a line ended not with an EOL but with a 0 or NULL if the end of the
- file is reached */
- char *readLine(FILE *file, char *line, int sizeOfLine)
- {
- int line_length;
- if (fgets(line, sizeOfLine, file) != NULL)
- {
- line_length = strlen(line)-1;
- line[line_length] = 0;
- }
- else
- {
- line = NULL;
- }
- return line;
- }
- /**
- * Creates a DNSEntry variable from the content of a file line and links it
- * to the DNSTable.
- * @param line the line from the file to be parsed
- * @param delim the character between tokens.
- */
- struct _DNSEntry* buildADNSEntryFromALine(char *line, char *token_delim)
- {
- char *token;
- struct _IP *ip_struct = malloc(sizeof(struct _IP));
- struct _IP *last_ip_struct;
- struct _DNSEntry* dnsEntry = malloc(sizeof(struct _DNSEntry));
- int firstIP = 1;
- //getting the domain name
- token = strtok(line, token_delim);
- strcpy(dnsEntry->domainName, token);
- dnsEntry->numberOfIPs = 0;
- //getting the Ip's
- while ((token = strtok(NULL, token_delim)) != NULL)
- {
- ip_struct = malloc(sizeof(struct _IP));
- inet_aton((const char*)token, &(ip_struct->IP));
- ip_struct->nextIP = NULL;
- (dnsEntry->numberOfIPs)++;
- if (firstIP == 1)
- {
- dnsEntry->first_ip = ip_struct;
- last_ip_struct = ip_struct;
- firstIP = 0;
- }
- else
- {
- last_ip_struct->nextIP = ip_struct;
- last_ip_struct = ip_struct;
- }
- }
- return dnsEntry;
- }
- /* Reads a file with the dns information and loads into a _DNSTable structure.
- Each line of the file is a DNS entry.
- RETURNS: the DNS table */
- struct _DNSTable* loadDNSTableFromFile(char *fileName)
- {
- FILE *file;
- char line[1024];
- struct _DNSEntry *dnsEntry;
- struct _DNSEntry *lastDNSEntry;
- struct _DNSTable *dnsTable = malloc(sizeof(struct _DNSTable));
- int firstDNSEntry = 1;
- file = fopen(fileName, "r");
- if (file==NULL)
- {
- perror("Problems opening the file");
- printf("Errno: %d \n", errno);
- }
- else
- {
- //reading the following entries in the file
- while(readLine(file, line, sizeof(line)) != NULL)
- {
- dnsEntry = buildADNSEntryFromALine(line, " ");
- dnsEntry->nextDNSEntry = NULL;
- if (firstDNSEntry == 1)
- {
- dnsTable->first_DNSentry = dnsEntry;
- lastDNSEntry = dnsEntry;
- firstDNSEntry = 0;
- }
- else
- {
- lastDNSEntry->nextDNSEntry = dnsEntry;
- lastDNSEntry = dnsEntry;
- }
- }
- fclose(file);
- }
- return dnsTable;
- }
- /**
- * Calculates the size of the message containing the DNS table. It does not
- * include the message identifier.
- * @param dnsTable a pointer to the DNSTable in memory.
- */
- int getDNSTableMSGSize(struct _DNSTable* dnsTable)
- {
- int table_size = 0;
- int numberOfIPs_BYTES_SIZE = sizeof(short);
- struct _DNSEntry *dnsEntry;
- dnsEntry = dnsTable->first_DNSentry;
- if(dnsEntry != NULL)
- {
- do
- {
- table_size += ( strlen(dnsEntry->domainName) + SPACE_BYTE_SIZE +
- numberOfIPs_BYTES_SIZE + (dnsEntry->numberOfIPs * sizeof (long)) );
- }while((dnsEntry=dnsEntry->nextDNSEntry) != NULL);
- }
- return table_size;
- }
- /*Return a pointer to the last character copied in next_DNSEntry_ptr + 1 */
- /**
- * Converts the DNSEntry passed as a parameter into a byte array pointed by
- * next_DNSEntry_ptr. The representation will be
- * domain_name\0number_of_ips[4byte_ip]*].
- * @param dnsEntry the DNSEntry to be converted to a Byte Array.
- * @param next_DNSEntry_ptr a pointer to Byte Array where to start copying
- * the DNSEntry. The pointer moves to the end of the ByteArray representation.
- */
- void dnsEntryToByteArray(struct _DNSEntry* dnsEntry, char **next_DNSEntry_ptr)
- {
- struct _IP* pIP;
- fflush(stdout);
- strcpy(*next_DNSEntry_ptr, dnsEntry->domainName);
- //we leave one 0 between the name and the number of IP's of the domain
- *next_DNSEntry_ptr += (strlen(dnsEntry->domainName) + 1);
- stshort(dnsEntry->numberOfIPs, *next_DNSEntry_ptr);
- *next_DNSEntry_ptr += sizeof(short);
- if((pIP = dnsEntry->first_ip) != NULL)
- {
- do
- {
- stlong(pIP->IP.s_addr, *next_DNSEntry_ptr);
- *next_DNSEntry_ptr += sizeof(long);
- }while((pIP = pIP->nextIP) != NULL);
- }
- }
- /*Dumps the dnstable into a byte array*/
- /*@Return a pointer to the byte array representing the DNS table */
- /*@param dnsTable the table to be serialized into an array of byes */
- /*@param _tableSize reference parameter that will be filled with the table size*/
- char *dnsTableToByteArray(struct _DNSTable* dnsTable, int *_tableSize)
- {
- int tableSize = getDNSTableMSGSize(dnsTable);
- *_tableSize = tableSize;
- char *dns_as_byteArray = malloc(tableSize);
- char *next_dns_entry_in_the_dns_byteArray_ptr = dns_as_byteArray;
- struct _DNSEntry *dnsEntry;
- bzero(dns_as_byteArray, tableSize);
- dnsEntry = dnsTable->first_DNSentry;
- do
- {
- dnsEntryToByteArray(dnsEntry, &next_dns_entry_in_the_dns_byteArray_ptr);
- }while((dnsEntry=dnsEntry->nextDNSEntry) != NULL);
- return dns_as_byteArray;
- }
- /**
- * Function that gets the dns_file name and port options from the program
- * execution.
- * @param argc the number of execution parameters
- * @param argv the execution parameters
- * @param reference parameter to set the dns_file name.
- * @param reference parameter to set the port. If no port is specified
- * the DEFAULT_PORT is returned.
- */
- int getProgramOptions(int argc, char* argv[], char *dns_file, int *_port)
- {
- int param;
- int port = DEFAULT_PORT;
- // We process the application execution parameters.
- while((param = getopt(argc, argv, "f:p:")) != -1){
- switch((char) param){
- case 'f':
- strcpy(dns_file, optarg);
- break;
- case 'p':
- // Donat que hem inicialitzat amb valor DEFAULT_PORT (veure common.h)
- // la variable port, aquest codi nomes canvia el valor de port en cas
- // que haguem especificat un port diferent amb la opcio -p
- *_port = atoi(optarg);
- break;
- default:
- printf("Parametre %c desconegut\n\n", (char) param);
- return -1;
- }
- }
- return 0;
- }
- /**
- * Function that generates the array of bytes with the dnsTable data and
- * sends it.
- * @param s the socket connected to the client.
- * @param dnsTable the table with all the domains
- */
- void process_LIST_RQ_msg(int sock, struct _DNSTable *dnsTable)
- {
- char *dns_table_as_byteArray;
- char *msg;
- int dns_table_size;
- int msg_size = 2;
- dns_table_as_byteArray = dnsTableToByteArray(dnsTable, &dns_table_size);
- msg_size += dns_table_size;
- msg = malloc(dns_table_size + 2);
- //TODO: set the operation code and the table data
- stshort(4, msg); // Ponemos el codigo de operacion al mensaje a enviar
- memcpy(msg+2, dns_table_as_byteArray, msg_size-2); // copiamos la tabla a la cadena de chars msg
- //TODO: send the message
- if(send(sock, msg, msg_size, 0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] SENDING \n---------------------------------------------------\n%s",KRED,KWHT);
- }
- }
- void process_HELLO_RQ_msg(int sock){
- char buffer[MAX_BUFF_SIZE];
- bzero(buffer,sizeof(buffer));
- stshort(2,buffer);
- strcpy(buffer+2,"HELLOWORLD");
- if(send(sock,buffer,300,0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] CANNOT SEND HELLOWORLD TO CLIENT \n---------------------------------------------------\n%s",KRED,KWHT);
- }
- else{
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] SEND HELLOWORLD TO CLIENT \n---------------------------------------------------\n%s",KCYN,KWHT);
- }
- }
- void process_DOMAIN_RQ_msg(int sock, struct _DNSTable *dnsTable){
- char buffer[MAX_BUFF_SIZE];
- bzero(buffer,sizeof(buffer));
- char *sdominio=NULL;
- char ipdominio[MAX_BUFF_SIZE];
- int i=0;
- int booleano=0;
- int num=0;
- int n_bytes;
- int sizlng=0;
- struct _DNSEntry *dnsEntry= dnsTable->first_DNSentry;
- struct _IP *pIP;
- n_bytes=recv(sock, buffer, sizeof(buffer), 0);
- bzero(ipdominio,sizeof(buffer));
- sdominio=strtok(buffer,"\0");
- /*memcpy(sdominio,buffer,n_bytes);
- printf("hola\n");
- strcpy(buffer,sdominio);*/
- printf("El cliente pide la IP de:%s\n",sdominio);
- while(dnsEntry->nextDNSEntry+1 != NULL && booleano!=1){
- if(strcmp(dnsEntry->domainName,sdominio)==0){
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] DOMINIO ENCONTRADO EN DNS.TXT \n---------------------------------------------------\n%s",KMAG,KWHT);
- num=(dnsEntry->numberOfIPs);
- printf("%d \n",num);
- bzero(ipdominio,sizeof(buffer));
- stshort(6,ipdominio);
- pIP=dnsEntry->first_ip;
- for( i=0; i<num;i++){
- printf("%s\n",inet_ntoa(pIP->IP));
- stlong(pIP->IP.s_addr,ipdominio+2+sizlng);
- sizlng+=sizeof(long);
- //strcat(concatenated,inet_ntoa(dnsTable->first_DNSentry->first_ip->IP));
- //strcat(concatenated,"\n");
- pIP=pIP->nextIP;
- } // end for*/
- booleano=1;
- if(send(sock,ipdominio,sizlng+2,0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] CANNOT SEND IP TO CLIENT \n---------------------------------------------------\n%s",KRED,KWHT);
- }//end if (send
- else{
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] SEND IPS FROM DOMAIN TO SERVER \n---------------------------------------------------\n%s",KYEL,KWHT);
- }
- }//cierra el if del strcmp
- else{
- dnsEntry=dnsEntry->nextDNSEntry;
- }
- }//cierra el while
- if(booleano==0){
- char *msg;
- stshort(12,msg);
- if(send(sock,msg,sizeof(buffer),0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] CANNOT SEND IP TO CLIENT \n---------------------------------------------------\n%s",KRED,KWHT);
- }//end if (send
- else{
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] SEND IPS FROM DOMAIN TO SERVER \n---------------------------------------------------\n%s",KYEL,KWHT);
- }
- }
- }
- void process_CHANGE_RQ_msg(int sock, struct _DNSTable *dnsTable){
- char buffer[MAX_BUFF_SIZE];
- bzero(buffer,sizeof(buffer));
- char *sdominio;
- char *ipdominio;
- char domain[MAX_BUFF_SIZE];
- int i=0;
- int booleano=0;
- int num=0;
- int n_bytes;
- int sizlng=0;
- char IP[MAX_BUFF_SIZE];
- char *token;
- const char delim[2] = "·";
- const char delim2[2] = "/";
- struct _DNSEntry *dnsEntry= dnsTable->first_DNSentry;
- struct in_addr *pIP;
- n_bytes=recv(sock, buffer, sizeof(buffer), 0);
- memcpy(sdominio,buffer,n_bytes);
- strcpy(buffer,sdominio);
- printf("Recidido %s \n",sdominio);
- token = strtok(sdominio,delim);
- memcpy(domain, token, strlen(token)+1);
- printf("El dominio es = %s\n", domain);
- token = strtok(NULL, delim);
- memcpy(IP, token, strlen(token)+1);
- token = strtok(IP, delim2);
- printf("%stoken2\n",token);
- token = strtok(NULL, delim2);
- printf ("La IP es: %s\n", token);
- //--RECORRER LOS DOMINIOS----------------------------
- inet_aton(IP, &pIP);
- while(dnsEntry->nextDNSEntry != NULL && booleano!=1){
- if(strcmp(dnsEntry->domainName,domain)==0){
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] DOMINIO ENCONTRADO EN DNS.TXT \n---------------------------------------------------\n%s",KMAG,KWHT);
- num=(dnsEntry->numberOfIPs);
- printf("%d \n",num);
- bzero(ipdominio,sizeof(buffer));
- stshort(11,ipdominio);
- //dnsEntry->first_ip->IP.s_addr=pIP;
- printf("holaIpdone\n");
- booleano=1;
- if(send(sock,ipdominio,sizeof(buffer),0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] CANNOT SEND IP TO CLIENT \n---------------------------------------------------\n%s",KRED,KWHT);
- }//end if (send
- else{
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] CHANGED IP FROM DOMAIN \n---------------------------------------------------\n%s",KYEL,KWHT);
- }
- }//cierra el if del strcmp
- else{ // no encontramos, probamos la siguiente
- dnsEntry=dnsEntry->nextDNSEntry;
- }
- }//cierra el while
- if(booleano==0){ // ENVIAR ERROR
- char *msg;
- stshort(12,msg);
- if(send(sock,msg,sizeof(buffer),0)==-1){
- printf("%s\n---------------------------------------------------\n[ERROR] CANNOT SEND IP TO CLIENT \n---------------------------------------------------\n%s",KRED,KWHT);
- }//end if (send
- else{
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] SEND IPS FROM DOMAIN TO SERVER \n---------------------------------------------------\n%s",KYEL,KWHT);
- }
- }
- }
- void process_ADD_DOMAIN(int sock, char *buffer, struct _DNSTable *dnsTable, int bytes)
- {
- printf("\n------------------AÑADIR IP A UN DOMINIO ---------------------------\n");
- char nom_host[NAME_LENGTH];//on rebrem el nom del domini
- char ip_b[20];//on guardem la ip a inserir
- struct _DNSEntry *entry = dnsTable->first_DNSentry;
- struct _DNSEntry *newentry = malloc(sizeof(struct _DNSEntry));
- struct _DNSEntry *preventry;
- struct _IP *ip = malloc(sizeof(struct _IP));
- struct _IP *last_ip;
- int done = 1;
- int desp = 2;
- int firstIP = 1;
- memset(nom_host,'\0', sizeof(nom_host));
- memcpy(nom_host, buffer+desp, sizeof(nom_host));
- desp += strlen(nom_host)+1;
- while((entry != NULL) && (done != 0)){
- done = strcmp(entry->domainName,nom_host);
- if(done != 0){
- preventry = entry;
- entry = entry->nextDNSEntry;
- }
- }
- if(entry == NULL){ //si es un nuevo dominio
- strcpy(newentry->domainName, nom_host);
- do{
- ip = malloc(sizeof(struct _IP));
- memcpy(ip_b, buffer+desp, sizeof(unsigned long));
- ip->IP.s_addr = ldlong(ip_b);
- ip->nextIP = NULL;
- (newentry->numberOfIPs)++;
- if(firstIP == 1){
- newentry->first_ip = ip;
- last_ip = ip;
- firstIP = 0;
- }
- else{
- last_ip->nextIP = ip;
- last_ip = ip;
- }
- desp += sizeof(unsigned long);
- }while(desp < bytes);
- newentry->nextDNSEntry = NULL;
- preventry->nextDNSEntry = newentry;
- } // FIN DE AÑADIR A UN DOMINIO QUE NO EXISTE
- else{ //si el dominio ya existe
- printf ("Adding Ip for :%s\n",entry->domainName);
- last_ip = entry->first_ip;
- while(last_ip->nextIP != NULL){
- last_ip = last_ip->nextIP;
- }
- do{
- printf("holahellegado al do\n");
- ip = malloc(sizeof(struct _IP));
- memcpy(ip_b, buffer+desp, sizeof(unsigned long));
- ip->IP.s_addr = ldlong(ip_b);
- ip->nextIP = NULL;
- (entry->numberOfIPs)++;
- last_ip->nextIP = ip;
- last_ip = ip;
- desp += sizeof(unsigned long);
- }while(desp < bytes);
- printf("holafindeldo\n");
- }//FIN ELSE
- send_OPOK(sock);
- printf("\n-------------------FI DEL PROCES AFEGIR IP-------------------------\n");
- return(0);
- }
- void send_OPOK(int s)
- {
- char msg[2];
- stshort(MSG_OP_OK, msg);
- send(s, msg, sizeof(msg), 0);
- }
- /**
- * Receives and process the request from a client.
- * @param s the socket connected to the client.
- * @param dnsTable the table with all the domains
- * @return 1 if the user has exit the client application therefore the
- * connection whith the client has to be closed. 0 if the user is still
- * interacting with the client application.
- */
- int process_msg(int sock, struct _DNSTable *dnsTable)
- {
- unsigned short op_code=0;
- char buffer[MAX_BUFF_SIZE];
- bzero(buffer,sizeof(buffer));
- int n_bytes;
- int done = 0;
- printf("%s\n---------------------------------------------------\n[SUCCESFUL] CLIENT CONNECTED WITH SERVER \n---------------------------------------------------\n%s",KCYN,KWHT);
- ;
- if((n_bytes=recv(sock, buffer, sizeof(buffer), 0))==-1){
- printf("No recibe el server\n");
- exit(-1);}
- op_code = ldshort(buffer);
- switch(op_code)
- {
- case MSG_HELLO_RQ:
- process_HELLO_RQ_msg(sock);
- break;
- case MSG_LIST_RQ:
- process_LIST_RQ_msg(sock, dnsTable);
- break;
- case MSG_DOMAIN_RQ:
- process_DOMAIN_RQ_msg(sock, dnsTable);
- break;
- case MSG_ADD_DOMAIN:
- process_ADD_DOMAIN(sock, buffer, dnsTable, n_bytes);
- break;
- case MSG_CHANGE_DOMAIN:
- process_CHANGE_RQ_msg(sock, dnsTable);
- break;
- case MSG_FINISH:
- //TODO
- done = 1;
- break;
- default:
- perror("Message code does not exist.\n"); }
- return done;
- }
- int main (int argc, char * argv[])
- {
- struct _DNSTable *dnsTable;
- int port;
- char dns_file[MAX_FILE_NAME_SIZE] ;
- getProgramOptions(argc, argv, dns_file, &port);
- dnsTable = loadDNSTableFromFile(dns_file);
- printDNSTable(dnsTable);
- //-----------------------------------------------------------------------------//
- //A BORRAR
- int pid; // fork
- int goexit = 0;
- //--------------
- struct sockaddr_in serverAdr;
- struct sockaddr_storage serverAlmacenamiento;
- int fd1, fd2; // sockets
- socklen_t addr_size; // tamaño direccion
- //Creamos los sockets
- if((fd1=socket(AF_INET, SOCK_STREAM,0))==-1){
- perror("\n---------------------------------------------------\n[ERROR] SOCKET \n---------------------------------------------------\n");
- exit(-1);
- }
- //Struct de la direccion del server
- serverAdr.sin_family = AF_INET;
- // Poner Puerto usando htons para el orden de los bytes
- serverAdr.sin_port= htons(DEFAULT_PORT);
- // Poner la IP --> Localhost
- serverAdr.sin_addr.s_addr = INADDR_ANY;
- //Poner todos los bits a 0
- memset(serverAdr.sin_zero,'\0',sizeof serverAdr.sin_zero);
- //LA funcion bind asocia el socket dado por sockfd a la direccion local
- //especificada por addr, para que el socket quede asignado al puerto
- if((bind(fd1, (struct sockaddr *)&serverAdr, sizeof(serverAdr))==-1)){
- perror("\n---------------------------------------------------\n[ERROR] BINDING \n---------------------------------------------------\n");
- exit(-1);
- }
- printf("%s\n---------------------------------------------------\n[SUCCESSFUL] BINDING \n---------------------------------------------------\n%s",KYEL,KNRM);
- //Listen especifica que el socket desea aceptar conexiones
- if(listen(fd1,100)==-1){
- perror("Error in listen()");
- }
- printf("%s\n---------------------------------------------------\n[SUCCESSFUL] SERVER IS LISTENING\n---------------------------------------------------\n%s",KYEL,KNRM);
- addr_size = sizeof serverAlmacenamiento;
- while(1) {
- goexit=0;
- //Accept devuelve un nuevo socket para la conexion (peticion)
- printf("hola\n");
- if((fd2 = accept(fd1, (struct sockaddr *) &serverAlmacenamiento, &addr_size))==-1){
- perror("\n---------------------------------------------------\n[ERROR] ACCEPTING \n---------------------------------------------------\n");
- exit(-1);
- }
- printf("%s\n---------------------------------------------------\n[SUCCESSFUL] ACCEPT \n---------------------------------------------------\n%s",KYEL,KWHT);
- pid=fork();
- if(pid>0){
- //pare
- close(fd2);
- }
- else{
- close(fd1);
- while( goexit == 0){ goexit= process_msg(fd2, dnsTable);} // fork hijo
- exit(0);
- }
- }
- // pare tanca fd2 -->
- printf("%s",KWHT);
- printf("FIN\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement