/* return 1 on success. * return 0 if no data received. * return -1 on failure (connection refused). */ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) { char success[] = "200"; uint8_t data[16]; // draining works the best if the length is a power of 2 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data) - 1); if (ret == -1) { return 0; } data[sizeof(data) - 1] = 0; if (strstr((char *)data, success)) { // drain all data unsigned int data_left = TCP_socket_data_recv_buffer(TCP_conn->sock); if (data_left) { VLA(uint8_t, temp_data, data_left); read_TCP_packet(TCP_conn->sock, temp_data, data_left); } return 1; } return -1; }
/* Read length bytes from socket. * * return length on success * return -1 on failure/no data in buffer. */ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length) { unsigned int count = TCP_socket_data_recv_buffer(sock); if (count >= length) { int len = recv(sock, (char *)data, length, MSG_NOSIGNAL); if (len != length) { fprintf(stderr, "FAIL recv packet\n"); return -1; } return len; } return -1; }
/* Read the next two bytes in TCP stream then convert them to * length (host byte order). * * return length on success * return 0 if nothing has been read from socket. * return ~0 on failure. */ uint16_t read_TCP_length(sock_t sock) { unsigned int count = TCP_socket_data_recv_buffer(sock); if (count >= sizeof(uint16_t)) { uint16_t length; int len = recv(sock, (char *)&length, sizeof(uint16_t), MSG_NOSIGNAL); if (len != sizeof(uint16_t)) { fprintf(stderr, "FAIL recv packet\n"); return 0; } length = ntohs(length); if (length > MAX_PACKET_SIZE) { return ~0; } return length; } return 0; }