/* * 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; }
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; } }