int client_worker(SOCKET clientsocket) { static uint8_t buffer[BUF_LEN]; size_t readed_length = 0; size_t out_len = BUF_LEN; int written = 0; enum ws_frame_type frame_type = WS_INCOMPLETE_FRAME; struct handshake hs; nullhandshake(&hs); // read openinig handshake while (frame_type == WS_INCOMPLETE_FRAME) { int readed = recv(clientsocket, buffer+readed_length, BUF_LEN-readed_length, 0); if (!readed) { fprintf(stderr, "Recv failed: %d\n", WSAGetLastError()); closesocket(clientsocket); return EXIT_FAILURE; } #ifdef PACKET_DUMP printf("In packet:\n"); fwrite(buffer, 1, readed, stdout); printf("\n"); #endif readed_length+= readed; assert(readed_length <= BUF_LEN); frame_type = ws_parse_handshake(buffer, readed_length, &hs); if (frame_type == WS_INCOMPLETE_FRAME && readed_length == BUF_LEN) { fprintf(stderr, "Buffer too small\n"); closesocket(clientsocket); return EXIT_FAILURE; } else if (frame_type == WS_ERROR_FRAME) { fprintf(stderr, "Error in incoming frame\n"); closesocket(clientsocket); return EXIT_FAILURE; } } assert(frame_type == WS_OPENING_FRAME); // if resource is right, generate answer handshake and send it if (strcmp(hs.resource, "/echo") != 0) { fprintf(stderr, "Resource is wrong:%s\n", hs.resource); closesocket(clientsocket); return EXIT_FAILURE; } out_len = BUF_LEN; ws_get_handshake_answer(&hs, buffer, &out_len); #ifdef PACKET_DUMP printf("Out packet:\n"); fwrite(buffer, 1, out_len, stdout); printf("\n"); #endif written = send(clientsocket, buffer, out_len, 0); if (written == SOCKET_ERROR) { fprintf(stderr, "Send failed: %d\n", WSAGetLastError()); closesocket(clientsocket); return EXIT_FAILURE; } if (written != out_len) { fprintf(stderr, "Written %d of %d\n", written, out_len); closesocket(clientsocket); return EXIT_FAILURE; } // connect success! // read incoming packet and parse it; readed_length = 0; frame_type = WS_INCOMPLETE_FRAME; while (frame_type == WS_INCOMPLETE_FRAME) { int readed = recv(clientsocket, buffer+readed_length, BUF_LEN-readed_length, 0); if (!readed) { fprintf(stderr, "Recv failed: %d\n", WSAGetLastError()); closesocket(clientsocket); return EXIT_FAILURE; } #ifdef PACKET_DUMP printf("In packet:\n"); fwrite(buffer, 1, readed, stdout); printf("\n"); #endif readed_length+= readed; assert(readed_length <= BUF_LEN); size_t data_len; uint8_t *data; frame_type = ws_parse_input_frame(buffer, readed_length, &data, &data_len); if (frame_type == WS_INCOMPLETE_FRAME && readed_length == BUF_LEN) { fprintf(stderr, "Buffer too small\n"); closesocket(clientsocket); return EXIT_FAILURE; } else if (frame_type == WS_CLOSING_FRAME) { send(clientsocket, "\xFF\x00", 2, 0); // send closing frame closesocket(clientsocket); // and close connection break; } else if (frame_type == WS_ERROR_FRAME) { fprintf(stderr, "Error in incoming frame\n"); closesocket(clientsocket); return EXIT_FAILURE; } else if (frame_type == WS_TEXT_FRAME) { out_len = BUF_LEN; frame_type = ws_make_frame(data, data_len, buffer, &out_len, WS_TEXT_FRAME); if (frame_type != WS_TEXT_FRAME) { fprintf(stderr, "Make frame failed\n"); closesocket(clientsocket); return EXIT_FAILURE; } #ifdef PACKET_DUMP printf("Out packet:\n"); fwrite(buffer, 1, out_len, stdout); printf("\n"); #endif written = send(clientsocket, buffer, out_len, 0); if (written == SOCKET_ERROR) { fprintf(stderr, "Send failed: %d\n", WSAGetLastError()); closesocket(clientsocket); return EXIT_FAILURE; } if (written != out_len) { fprintf(stderr, "Written %d of %d\n", written, out_len); closesocket(clientsocket); return EXIT_FAILURE; } readed_length = 0; frame_type = WS_INCOMPLETE_FRAME; } } // read/write cycle closesocket(clientsocket); return EXIT_SUCCESS; }
int client_worker(int clientsocket) { static uint8_t buffer[BW_READ_BUF_SIZE]; static uint8_t buffer2[BW_READ_BUF_SIZE]; size_t num_read = 0; size_t out_len = BW_READ_BUF_SIZE; int written = 0; int stdout_len = 0; enum ws_frame_type frame_type = WS_INCOMPLETE_FRAME; struct handshake hs; char * pch; size_t data_len; uint8_t *data; nullhandshake(&hs); while(frame_type == WS_INCOMPLETE_FRAME) { int read = recv(clientsocket, buffer+num_read, BW_READ_BUF_SIZE, 0); if (!read) { fprintf(stderr, "Recv failed, closing."); return -1; } num_read += read; frame_type = ws_parse_handshake(buffer, num_read, &hs); if (frame_type == WS_INCOMPLETE_FRAME && num_read == BW_READ_BUF_SIZE) { fprintf(stderr, "Buffer too small\n"); return -1; } else if (frame_type == WS_ERROR_FRAME) { fprintf(stderr, "Error in incoming frame\n"); return -1; } } if (strcmp(hs.resource, "/raw") != 0) { fprintf(stderr, "Resource is wrong:%s\n", hs.resource); return -1; } ws_get_handshake_answer(&hs, buffer, &out_len); written = send(clientsocket, buffer, out_len, 0); if (written <= 0) { fprintf(stderr, "Send failed.\n"); return -1; } if (written != out_len) { fprintf(stderr, "Written %d of %d\n", written, (int)out_len); return -1; } // connect success! // read incoming packet write them to stdout num_read = 0; frame_type = WS_INCOMPLETE_FRAME; while (frame_type == WS_INCOMPLETE_FRAME) { int read = recv(clientsocket, buffer+num_read, BW_READ_BUF_SIZE-num_read, 0); if (read <= 0) { fprintf(stderr, "Recv failed.\n"); return -1; } num_read += read; frame_type = ws_parse_input_frame(buffer, num_read, &data, &data_len); if (frame_type == WS_INCOMPLETE_FRAME && num_read == BW_READ_BUF_SIZE) { fprintf(stderr, "Buffer too small\n"); return -1; } else if (frame_type == WS_CLOSING_FRAME) { send(clientsocket, "\xFF\x00", 2, 0); // send closing frame break; } else if (frame_type == WS_ERROR_FRAME) { fprintf(stderr, "Error in incoming frame\n"); return -1; } else if (frame_type == WS_TEXT_FRAME) { out_len = BW_READ_BUF_SIZE; frame_type = ws_make_frame(data, data_len, buffer, &out_len, WS_TEXT_FRAME); if (frame_type != WS_TEXT_FRAME) { fprintf(stderr, "Make frame failed\n"); return -1; } stdout_len = 0; buffer[out_len-1] = '\0'; pch = strtok((char*)buffer+1, " "); while (pch != NULL) { uint8_t byte; byte = (uint8_t)strtoul(pch, NULL, 16); buffer2[stdout_len++] = byte; pch = strtok(NULL, " "); } write(STDOUT_FILENO, buffer2, stdout_len); num_read = 0; frame_type = WS_INCOMPLETE_FRAME; } } return 0; }