Пример #1
0
void atender_UMC(t_paquete *paquete, int socket_conexion) {

	int id_mensaje_recibido = paquete->header->id_mensaje;
	int id_proceso_emisor = paquete->header->id_proceso_emisor;
	int retorno_de_funcion;

	switch (id_mensaje_recibido) {

		case MENSAJE_HANDSHAKE:
			//TODO: Tomar valor de pagina
			log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 0] handshake");

			if(id_proceso_emisor == PROCESO_UMC)
				enviar_header_al_UMC(socket_conexion, RESPUESTA_HANDSHAKE);
			else
				handshake_error(socket_conexion);

			break;


		case MENSAJE_LEER_PAGINA_PARA_ESCRIBIR:
		case MENSAJE_LEER_PAGINA:
			//TODO: Revisar/evaluar si el umc estaba pidiendo desde la pagina 1 porque piensa que es la primera (debería de ser 0? revisar). no debería, porque a priori las lecturas les dieron resultados correctos a los chicos, si no explotaria feo
			log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 1-6] leer_pagina");

			t_pagina *pagina = malloc (sizeof (t_pagina));
			deserializar_pagina(paquete->payload, pagina);

			t_pagina_completa *pagina_completa_lectura= malloc (sizeof (t_pagina_completa)); //Se va a usar para responder ok
			pagina_completa_lectura->id_programa = pagina->id_programa;
			pagina_completa_lectura->pagina = pagina->pagina;
			pagina_completa_lectura->offset = pagina->offset;
			pagina_completa_lectura->tamanio = pagina->tamanio;
			pagina_completa_lectura->socket_pedido = pagina->socket_pedido;
			pagina_completa_lectura->valor = malloc(pagina->tamanio);


			retorno_de_funcion = leer_bytes_swap(pagina, pagina_completa_lectura->valor);


			t_buffer *buffer_pagina = serializar_pagina(pagina);
			t_buffer *buffer_pagina_completa_lectura = serializar_pagina_completa(pagina_completa_lectura);

			//Diferentes retornos de mensajes dependiendo de la situación. PD: Si quedó horrible pero el tiempo está en nuestra contra :P
			if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_LEER_PAGINA, buffer_pagina_completa_lectura);
			else if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA_PARA_ESCRIBIR)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_LEER_PAGINA_PARA_ESCRIBIR, buffer_pagina_completa_lectura);

			else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_LEER_PAGINA, buffer_pagina);
			else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_LEER_PAGINA_PARA_ESCRIBIR)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_LEER_PAGINA_PARA_ESCRIBIR, buffer_pagina);

			free (pagina);
			free (pagina_completa_lectura->valor);
			free (pagina_completa_lectura);
			free (buffer_pagina->contenido_buffer);
			free (buffer_pagina);
			free (buffer_pagina_completa_lectura->contenido_buffer);
			free (buffer_pagina_completa_lectura);

			break;


		case MENSAJE_ESCRIBIR_PAGINA_NUEVA:
		case MENSAJE_ESCRIBIR_PAGINA:

			log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 2-7] escribir_pagina");
			t_pagina_completa *pagina_completa_escritura = malloc (sizeof (t_pagina_completa));
			deserializar_pagina_completa(paquete->payload , pagina_completa_escritura);

			retorno_de_funcion = escribir_bytes_swap(pagina_completa_escritura);

			t_buffer *buffer_pagina_completa_escritura = serializar_pagina_completa(pagina_completa_escritura);

			//Diferentes retornos de mensajes dependiendo de la situación. PD: Si quedó horrible pero el tiempo está en nuestra contra :P
			if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_ESCRIBIR_PAGINA, buffer_pagina_completa_escritura);
			else if (retorno_de_funcion != -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA_NUEVA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_ESCRIBIR_PAGINA_NUEVA, buffer_pagina_completa_escritura);

			else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_ESCRIBIR_PAGINA, buffer_pagina_completa_escritura);
			else if (retorno_de_funcion == -1 && id_mensaje_recibido == MENSAJE_ESCRIBIR_PAGINA_NUEVA)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_ESCRIBIR_PAGINA_NUEVA, buffer_pagina_completa_escritura);


			free (pagina_completa_escritura);
			free (buffer_pagina_completa_escritura->contenido_buffer);
			free (buffer_pagina_completa_escritura);

			break;



		case MENSAJE_INICIAR_PROGRAMA:

			log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 3] iniciar_programa");
			t_programa_nuevo *programa_nuevo = malloc (sizeof (t_programa_nuevo));
			deserializar_programa_nuevo(paquete->payload , programa_nuevo);

			retorno_de_funcion = inicializar_programa (programa_nuevo);

			t_buffer *buffer_con_programa_nuevo = serializar_programa_nuevo(programa_nuevo);

			if (retorno_de_funcion != -1)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_INICIALIZAR_PROGRAMA, buffer_con_programa_nuevo);
			else
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_INICIALIZAR_PROGRAMA, buffer_con_programa_nuevo);

			free (programa_nuevo);
			free (buffer_con_programa_nuevo->contenido_buffer);
			free (buffer_con_programa_nuevo);

			break;



		case MENSAJE_FINALIZAR_PROGRAMA:

			log_trace(loggerManager,"[Comunicacion UMC][Mensaje recibido - cod 4] finalizar_programa");

			t_programa *programa = malloc (sizeof (t_programa));
			deserializar_programa(paquete->payload, programa);

			retorno_de_funcion = finalizar_programa (programa);

			t_buffer *buffer_con_programa = serializar_programa(programa);

			if (retorno_de_funcion != -1)
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, RESPUESTA_FINALIZAR_PROGRAMA, buffer_con_programa);
			else
				enviar_mensaje_con_buffer_al_UMC(socket_conexion, ERROR_FINALIZAR_PROGRAMA, buffer_con_programa);

			free (programa);
			free(buffer_con_programa->contenido_buffer);
			free(buffer_con_programa);

			break;


		default:
			log_error(loggerManager,"[Comunicacion UMC] El código de mensaje: %i, no es un mensaje aceptado por el SWAP", id_mensaje_recibido);
			break;
	}
}
Пример #2
0
void *handleClient(void *args) {
	pthread_detach(pthread_self());
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
	pthread_cleanup_push(&cleanup_client, args);

	int buffer_length = 0, string_length = 1, reads = 1;

	ws_client *n = args;
	n->thread_id = pthread_self();

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

	char buffer[BUFFERSIZE];
	n->string = (char *) malloc(sizeof(char));

	if (n->string == NULL) {
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
		handshake_error("Couldn't allocate memory.", ERROR_INTERNAL, n);
		pthread_exit((void *) EXIT_FAILURE);
	}

	printf("Client connected with the following information:\n"
		   "\tSocket: %d\n"
		   "\tAddress: %s\n\n", n->socket_id, (char *) n->client_ip);
	printf("Checking whether client is valid ...\n\n");
	fflush(stdout);

	/**
	 * Getting headers and doing reallocation if headers is bigger than our
	 * allocated memory.
	 */
	do {
		memset(buffer, '\0', BUFFERSIZE);
		if ((buffer_length = recv(n->socket_id, buffer, BUFFERSIZE, 0)) <= 0){
			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
			handshake_error("Didn't receive any headers from the client.", 
					ERROR_BAD, n);
			pthread_exit((void *) EXIT_FAILURE);
		}

		if (reads == 1 && strlen(buffer) < 14) {
			handshake_error("SSL request is not supported yet.", 
					ERROR_NOT_IMPL, n);
			pthread_exit((void *) EXIT_FAILURE);
		}

		string_length += buffer_length;

		char *tmp = realloc(n->string, string_length);
		if (tmp == NULL) {
			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
			handshake_error("Couldn't reallocate memory.", ERROR_INTERNAL, n);
			pthread_exit((void *) EXIT_FAILURE);
		}
		n->string = tmp;
		tmp = NULL;

		memset(n->string + (string_length-buffer_length-1), '\0', 
				buffer_length+1);
		memcpy(n->string + (string_length-buffer_length-1), buffer, 
				buffer_length);
		reads++;
	} while( strncmp("\r\n\r\n", n->string + (string_length-5), 4) != 0 
			&& strncmp("\n\n", n->string + (string_length-3), 2) != 0
			&& strncmp("\r\n\r\n", n->string + (string_length-8-5), 4) != 0
			&& strncmp("\n\n", n->string + (string_length-8-3), 2) != 0 );
	
	printf("User connected with the following headers:\n%s\n\n", n->string);
	fflush(stdout);

	ws_header *h = header_new();

	if (h == NULL) {
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
		handshake_error("Couldn't allocate memory.", ERROR_INTERNAL, n);
		pthread_exit((void *) EXIT_FAILURE);
	}

	n->headers = h;

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	if ( parseHeaders(n->string, n, port) < 0 ) {
		pthread_exit((void *) EXIT_FAILURE);
	}

	if ( sendHandshake(n) < 0 && n->headers->type != UNKNOWN ) {
		pthread_exit((void *) EXIT_FAILURE);	
	}	

	list_add(l, n);
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

	printf("Client has been validated and is now connected\n\n");
	printf("> ");
	fflush(stdout);

	uint64_t next_len = 0;
	char next[BUFFERSIZE];
	memset(next, '\0', BUFFERSIZE);

	while (1) {
		if ( communicate(n, next, next_len) != CONTINUE) {
			break;
		}

		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
		if (n->headers->protocol == CHAT) {
			list_multicast(l, n);
		} else if (n->headers->protocol == ECHO) {
			list_multicast_one(l, n, n->message);
		} else {
			list_multicast_one(l, n, n->message);
		}
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

		if (n->message != NULL) {
			memset(next, '\0', BUFFERSIZE);
			memcpy(next, n->message->next, n->message->next_len);
			next_len = n->message->next_len;
			message_free(n->message);
			free(n->message);
			n->message = NULL;	
		}
	}
	
	printf("Shutting client down..\n\n");
	printf("> ");
	fflush(stdout);

	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	list_remove(l, n);
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

	pthread_cleanup_pop(0);
	pthread_exit((void *) EXIT_SUCCESS);
}