Ejemplo n.º 1
0
/*
 * Create TCP socket and connect to ip:port.
 *
 * Return connected socket.
 */
static int setup_forward_tcp(int port, char *ip)
{
	int ret, sock;

	sock = tcp_create_socket();
	if (sock < 0) {
		goto error;
	}

	ret = tcp_connect_socket(sock, port, ip);
	if (ret < 0) {
		ERR("Unable to connect to TCP tunnel");
		fprintf(stderr,
				"Recommended to use ssh -L %s:%d:%s:53 HOST for tunneling\n",
				ip, port, dns_ip);
		goto error;
	}

	return sock;

error:
	return -1;
}
Ejemplo n.º 2
0
int main(void) {
    char decission[50];
    int s, sem;
    packet* rec = malloc(sizeof (packet));
    if(rec == NULL){
        ERR("malloc");
    }
    packet* tmp = malloc(sizeof (packet));
    if(tmp == NULL){
        ERR("malloc");
    }
    char c;
    int x, y, points,i;
    int isAnyTileAvaliable;
    semaphore_init(&sem, 'E', 1);
    
    /* Set signals handlers */
	if(sethandler(sigint_handler,SIGINT)) ERR("Setting SIGINT:");
	if(sethandler(sigterm_handler,SIGTERM)) ERR("Setting SIGTERM:");

    /*********  TCP IP  *********/
    s = tcp_connect_socket("localhost", 2000);

    printf("##############################\n");
    printf("## WELCOME TO SCRABBLE GAME ##\n");
    printf("##############################\n");


    while (g_doWork) {
        int t;

        if ((t = tcp_socket_read_packet(s, rec)) == 0 && g_doWork==1) {
            perror("Server closed connection client\n");
            break;
        } else if (t < 0) {
            perror("recv");
            break;
        }
        switch (rec->msg) {
            case NO_PLAYER:
                printf("Waiting for another player to connect...\n");
                break;
            case PAIR_MATCH:
                printf("Player found - starting the game...\n");
                break;
            case INFO:
                printf("Player found - starting the game...\n");
                scrabble_game_print_title();
                scrabble_game_print_board(rec->currentBoard);
                scrabble_game_print_wait_for_move();
                break;
            case REQUEST_MOVE:
                /* Print points in the right order */
                scrabble_game_print_title();
                scrabble_game_print_points(rec->p1Points, rec->p2Points, rec->playerType);

                /* Print current board state */
                scrabble_game_print_board(rec->currentBoard);

                /* Print available tiles */
                printf("----------------------------------------\n              ");
                scrabble_game_print_available_tiles(rec->tiles, 5);
                printf("----------------------------------------\n");
                isAnyTileAvaliable = 0;
                for(i=0; i<5;i++){
                    if(rec->tiles[i] != 'x'){
                        isAnyTileAvaliable = 1;
                    }
                }
                if(isAnyTileAvaliable == 1) {
                    points = 0;
                    if(-1 == gather_input(&c, &x, &y, &points, rec->tiles, rec->currentBoard)) {
                        printf("gater input error\n");
                    }else {
                        /* Print updated points */
                        scrabble_game_print_title();
                        if (rec->playerType == FIRST) rec->p1Points += points;
                        if (rec->playerType == SECOND) rec->p2Points += points;
                        scrabble_game_print_points(rec->p1Points, rec->p2Points, rec->playerType);

                        /* Print updated board */
                        rec->currentBoard[x][y] = c;
                        scrabble_game_print_board(rec->currentBoard);

                        /* Send data to server. */
                        tmp->msg = MOVE_DATA;
                        tmp->letter = c;
                        tmp->x_coord = x;
                        tmp->y_coord = y;
                        tmp->p1Points = rec->p1Points;
                        tmp->p2Points = rec->p2Points;
                        tcp_socket_send_packet(s, tmp);
                        scrabble_game_print_wait_for_move();
                    }
                }
                else{
                    printf("##########################################\n");
                    printf("##             END OF MATCH             ##\n");
                    printf("##########################################\n");
                    printf("Do you want to play another game?(Y/N)\n");
                    scanf(" %c", decission);
                    printf("%s \n",decission);
                    tmp->isMatchOngoing = -1;
                    if (decission[0] == 'Y') {
                        tmp->msg = PLAY_ANOTHER_GAME;
                        tcp_socket_send_packet(s, tmp);
                    }
                    else
                    {
                        tmp->msg = FINISH_GAME;
                        printf("isMatchOngoing = %d \n", tmp->isMatchOngoing);
                        tcp_socket_send_packet(s, tmp);
                        return EXIT_SUCCESS;
                    }
                }
                break;
            case DISCONNECTED:

                printf("##########################################\n");
                printf("##            Connection lost!          ##\n");
                printf("##########################################\n");
                printf("Sorry but connection with other player is\n");
                printf("lost. Do you want to play another game?(Y/N)\n");
                scanf(" %c", decission);
                printf("%s \n",decission);
                if (decission[0] == 'Y') {
                    tmp->msg = PLAY_ANOTHER_GAME;
                    tcp_socket_send_packet(s, tmp);
                } 
                else 
                {
                    tmp->msg = FINISH_GAME;
                    tcp_socket_send_packet(s, tmp);
                    return EXIT_SUCCESS;
                }
                break;
                
            case EXIT:
                printf("Server disconnected.\n");
                return EXIT_SUCCESS;
            default:
                printf("Cannot interpret packet's message: %d \n", rec->msg);
        }
    };
    printf("Disconnected\n");
    if(-1 == close(s)){
        ERR("close");
    }
    return 0;
}
//*****************************************
//*****************************************
//********** PROCESS HTTP CLIENT **********
//*****************************************
//*****************************************
//This function is automatically called by tcp_ip_process_stack().
void process_http_client (void)
{
	static BYTE our_tcp_client_socket = TCP_INVALID_SOCKET;
	static WORD our_tcp_client_local_port;
	static DEVICE_INFO remote_device_info;
	static BYTE eth_http_client_10ms_clock_timer_last;
	static DWORD http_client_content_length;
	static DWORD http_client_content_received;
	static BYTE header_started;
	static BYTE header_ended;
	static BYTE data_buffer[4];
	static BYTE content_length_match_char;



	//-------------------------
	//----- UPDATE TIMERS -----
	//-------------------------
	if ((BYTE)((BYTE)(ethernet_10ms_clock_timer & 0x000000ff) - eth_http_client_10ms_clock_timer_last) >=	10)
	{
		eth_http_client_10ms_clock_timer_last = (BYTE)(ethernet_10ms_clock_timer & 0x000000ff);
		
		//TIMEOUT TIMER
		if (http_client_100ms_timeout_timer)
			http_client_100ms_timeout_timer--;
	}

	if (
	(http_client_state != SM_HTTP_CLIENT_IDLE) &&
	((http_client_100ms_timeout_timer == 0) || (!nic_linked_and_ip_address_valid))
	)
	{
		http_client_state = SM_HTTP_CLIENT_FAIL;
	}



	if (our_tcp_client_socket != TCP_INVALID_SOCKET)
	{
		//----- CHECK OUR SOCKET HASN'T DISCONNECTED -----
		if ((tcp_socket[our_tcp_client_socket].sm_socket_state == SM_TCP_CLOSED) || (tcp_socket[our_tcp_client_socket].local_port != our_tcp_client_local_port))		//If the local port has changed then our socket was closed and taken by some other application process since we we're last called
			our_tcp_client_socket = TCP_INVALID_SOCKET;

		if (http_client_state == SM_HTTP_CLIENT_WAIT_FOR_DISCONNECT)
			http_client_state = SM_HTTP_CLIENT_IDLE;
		else if (http_client_state != SM_HTTP_CLIENT_IDLE)
			http_client_state = SM_HTTP_CLIENT_FAIL;
	}


	switch (http_client_state)
	{
	case SM_HTTP_CLIENT_IDLE:
		//----------------
		//----- IDLE -----
		//----------------
		tcp_close_socket(our_tcp_client_socket);			//Ensure socket is closed
		break;



	case SM_HTTP_CLIENT_RESOLVE_URL_START:
		//-----------------------------
		//----- RESOLVE URL START -----
		//-----------------------------
		//----- START NEW DNS QUERY -----
		if (do_dns_query(http_client_host_url, QNS_QUERY_TYPE_HOST))			//If false DNS query not currently available (already doing a query) - try again next time
			http_client_state = SM_HTTP_CLIENT_RESOLVE_URL_WAIT;



	case SM_HTTP_CLIENT_RESOLVE_URL_WAIT:
		//----------------------------
		//----- RESOLVE URL WAIT -----
		//----------------------------
	
		//----- IS DNS QUERY IS COMPLETE? -----
		remote_device_info.ip_address = check_dns_response();
		if (remote_device_info.ip_address.Val == 0xffffffff)
		{
			//DNS QUERY FAILED
			http_client_state = SM_HTTP_CLIENT_FAIL;		//(Timed out or invalid response)
		}
		else if (remote_device_info.ip_address.Val)
		{
			//DNS QUERY SUCESSFUL
            http_client_state = SM_HTTP_CLIENT_OPEN_SOCKET;
		}
		else
		{
			//DNS NOT YET COMPLETE
		}
		break;



	case SM_HTTP_CLIENT_OPEN_SOCKET:
		//-----------------------
		//----- OPEN SOCKET -----
		//-----------------------
		//remote_device_info.ip_address.Val =			//Already got
		remote_device_info.mac_address.v[0] = 0;		//Set to zero so TCP will automatically use ARP to find the MAC address
		remote_device_info.mac_address.v[1] = 0;
		remote_device_info.mac_address.v[2] = 0;
		remote_device_info.mac_address.v[3] = 0;
		remote_device_info.mac_address.v[4] = 0;
		remote_device_info.mac_address.v[5] = 0;
	
		//Connect to remote device port 80
		if (our_tcp_client_socket != TCP_INVALID_SOCKET)		//We shouldn't have a socket currently, but make sure
				tcp_close_socket(our_tcp_client_socket);
	
		our_tcp_client_socket = tcp_connect_socket(&remote_device_info, 80);	
		if (our_tcp_client_socket != TCP_INVALID_SOCKET)
		{	
			our_tcp_client_local_port = tcp_socket[our_tcp_client_socket].local_port;
			http_client_state = SM_HTTP_CLIENT_WAIT_FOR_CONNECTION;
			break;
		}
		//Could not open a socket - none currently available - keep trying
		break;
	


	case SM_HTTP_CLIENT_WAIT_FOR_CONNECTION:
		//--------------------------------------
		//----- WAIT FOR SOCKET TO CONNECT -----
		//--------------------------------------
		if (tcp_is_socket_connected(our_tcp_client_socket))
			http_client_state = SM_HTTP_CLIENT_TX_REQUEST;
	
		break;



	case SM_HTTP_CLIENT_TX_REQUEST:
		//----------------------------------------------
		//----- TX REQUEST PACKET TO REMOTE DEVICE -----
		//----------------------------------------------
		if (!tcp_setup_socket_tx(our_tcp_client_socket))
		{
			//Can't tx right now - try again next time
			break;
		}
	
		//WRITE THE TCP DATA
		http_client_send_const_string(http_client_request_text_get_start);
        http_client_send_const_string((CONSTANT BYTE*)http_client_filename);
		http_client_send_const_string(http_client_request_text_get_end);
		http_client_send_const_string(http_client_request_text_host_start);
        http_client_send_const_string((CONSTANT BYTE*)http_client_host_url);
		http_client_send_const_string(http_client_request_text_remainder);
	
		//SEND THE PACKET
		tcp_socket_tx_packet(our_tcp_client_socket);

		http_client_state = SM_HTTP_CLIENT_WAIT_FOR_RESPONSE;

		//Setup for receive (headers may span more than 1 packet)
		http_client_request_ok = 0;
		http_client_content_length = 0xffffffff;			//Default to length not specified by server
		http_client_content_received = 0;
		data_buffer[1] = data_buffer[2] = data_buffer[3] = 0x00;
		header_started = 0;
		header_ended = 0;
		content_length_match_char = 0;
		break;
	


	case SM_HTTP_CLIENT_WAIT_FOR_RESPONSE:
		//-----------------------------
		//----- WAIT FOR RESPONSE -----
		//-----------------------------
		if (tcp_check_socket_for_rx(our_tcp_client_socket))
		{
			//----- RESPONSE RECEIVED - PROCESS IT -----
			while (tcp_read_next_rx_byte(&data_buffer[0]))		//Function will return 0 if there are no more bytes to read
			{
				if ((data_buffer[0] != ' ') && (data_buffer[0] != 0x0d) && (data_buffer[0] != 0x0a))		//Ignore any leading blank lines before header
					header_started = 1;
				
				if ((data_buffer[3] == 0x0d) && (data_buffer[2] == 0x0a) && (data_buffer[1] == 0x0d) && (data_buffer[0] == 0x0a) && (header_started))
				{
					//----- END OF HEADER -----
					//File data follows
                    header_ended = 1;
					break;
				}
				else if ((data_buffer[3] == ' ') && (data_buffer[2] == '2') && (data_buffer[1] == '0') && (data_buffer[0] == '0'))
				{
					//----- 200 OK RESPONSE -----
					http_client_request_ok = 1;
				}

				//LOOK FOR CONTENT LENGTH
                if (content_length_match_char < 0xff)
				{
					if (content_length_match_char >= 15)
					{
						//WE ARE READING THE VALUE
						if (data_buffer[0] != ' ')
						{
							if ((data_buffer[0] < '0') || (data_buffer[0] > '9'))
							{
								//All done
								content_length_match_char = 0xff;
							}
							else
							{
								//Add next character to value
								http_client_content_length *= 10;
								http_client_content_length += (data_buffer[0] - 0x30);
							}
						}
					}
					else
					{
						//NOT MATCHED ENTIRE HEADER TITLE YET
						if (convert_character_to_lower_case(data_buffer[0]) == http_client_content_length_text[content_length_match_char])
							content_length_match_char++;
						else
							content_length_match_char = 0;
					}
				}

				data_buffer[3] = data_buffer[2];
				data_buffer[2] = data_buffer[1];
				data_buffer[1] = data_buffer[0];
			} //while (tcp_read_next_rx_byte(&data[0]))	

			//----- HEADER COMPLETE -----
			if (!http_client_request_ok)
			{
				//----- RESPONSE WAS NOT 200 OK - INFORM USER APPLICATION -----
                http_client_content_length = 0;
				HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(0, http_client_content_length, &http_client_host_url[0], &http_client_filename[0]);		//Send error message to user application
			}
			else if (!header_ended)
			{
				//----- OK RESPONSE BUT NOT REACHED THE END OF THE HEADERS YET -----
                tcp_dump_rx_packet();
				break;

			}
			else
			{
				//----- GET USER APPLICATION TO READ THE FILE DATA -----
                http_client_content_received += tcp_socket[our_tcp_client_socket].rx_data_bytes_remaining;
				HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(1, http_client_content_length, &http_client_host_url[0], &http_client_filename[0]);
				http_client_state = SM_HTTP_CLIENT_WAIT_FOR_RESPONSE_1;
			}

			//----- DUMP THE PACKET -----
			tcp_dump_rx_packet();
			
			if (http_client_content_received < http_client_content_length)
				http_client_state = SM_HTTP_CLIENT_WAIT_FOR_RESPONSE_1;
			else
				http_client_state = SM_HTTP_CLIENT_REQUEST_DISCONNECT;
		}
	
		if (tcp_does_socket_require_resend_of_last_packet(our_tcp_client_socket))
		{
			//----- RE-SEND LAST PACKET TRANSMITTED -----
			//(TCP requires resending of packets if they are not acknowledged and to avoid requiring a large RAM buffer the application needs to remember
			//the last packet sent on a socket so it can be resent if requried)
			http_client_state = SM_HTTP_CLIENT_TX_REQUEST;
		}
	
		if(!tcp_is_socket_connected(our_tcp_client_socket))
		{
			//----- THE CLIENT HAS DISCONNECTED -----
			HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(0xff, http_client_content_length, &http_client_host_url[0], &http_client_filename[0]);		//Send disconnect message to user application
			http_client_state = SM_HTTP_CLIENT_IDLE;
		}
		break;





	case SM_HTTP_CLIENT_WAIT_FOR_RESPONSE_1:
		//------------------------------------------------
		//----- WAIT FOR ADDITIONAL RESPONSE PACKETS -----
		//------------------------------------------------
		if (tcp_check_socket_for_rx(our_tcp_client_socket))
		{
			//----- RESPONSE RECEIVED - PROCESS IT -----

			//----- GET USER APPLICATION TO READ THE FILE DATA -----
            http_client_content_received += tcp_socket[our_tcp_client_socket].rx_data_bytes_remaining;
			HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(2, http_client_content_length, &http_client_host_url[0], &http_client_filename[0]);		//Send error message to user application

			//DUMP THE PACKET
			tcp_dump_rx_packet();

			if (http_client_content_received >= http_client_content_length)
				http_client_state = SM_HTTP_CLIENT_REQUEST_DISCONNECT;
		}

		if(!tcp_is_socket_connected(our_tcp_client_socket))
		{
			//----- THE CLIENT HAS DISCONNECTED -----
			HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(0xff, http_client_content_length, &http_client_host_url[0], &http_client_filename[0]);		//Send disconnect message to user application
			http_client_state = SM_HTTP_CLIENT_IDLE;
		}
		
		break;




	case SM_HTTP_CLIENT_REQUEST_DISCONNECT:
		//----------------------------------------------------
		//----- REQUEST TO DISCONNECT FROM REMOTE SERVER -----
		//----------------------------------------------------
		tcp_request_disconnect_socket (our_tcp_client_socket);
	
		http_client_state = SM_HTTP_CLIENT_WAIT_FOR_DISCONNECT;
		break;



	case SM_HTTP_CLIENT_WAIT_FOR_DISCONNECT:
		//----------------------------------------------
		//----- WAIT FOR SOCKET TO BE DISCONNECTED -----
		//----------------------------------------------	
		if (tcp_is_socket_closed(our_tcp_client_socket))
		{
			http_client_state = SM_HTTP_CLIENT_IDLE;
		}
		break;
	


	case SM_HTTP_CLIENT_FAIL:
		//--------------------------
		//----- PROCESS FAILED -----
		//--------------------------
        tcp_close_socket(our_tcp_client_socket);			//Ensure socket is closed

		HTTP_CLIENT_REQUEST_RECEIVE_FUNCTION(0, 0, &http_client_host_url[0], &http_client_filename[0]);		//Send error message to user application

        http_client_state = SM_HTTP_CLIENT_IDLE;
		break;
	}

}