// ======================================================================================================== // ======================================================================================================== // *********************************************** common.c *********************************************** // ======================================================================================================== // ======================================================================================================== #include "common.h" #include // ======================================================================================================== // ======================================================================================================== // For Regeneration & Enrollment , the token is the 'client' while the verifier is the 'server' Serve-up a socket for the client int OpenSocketServer(int str_length, int *server_socket_desc_ptr, char server_IP[str_length], int port_number, int *client_socket_desc_ptr, struct sockaddr_in *client_addr_ptr, int accept_only, int check_and_return) { struct sockaddr_in server_addr; int sizeof_sock; int queue_size = 20; // Create a socket and prepare the socket_in structure. if ( accept_only == 0 ) { // printf("OpenSocketServer(): Creating a socket\n"); fflush(stdout); *server_socket_desc_ptr = socket(AF_INET, SOCK_STREAM, 0); if ( *server_socket_desc_ptr == -1 ) { printf("ERROR: OpenSocketServer(): Could not create socket"); fflush(stdout); } // Do non-block fctrl call if ( check_and_return == 1 ) { int flags = fcntl(*server_socket_desc_ptr, F_GETFL, 0); if (flags < 0) return 0; flags = flags | O_NONBLOCK; if ( fcntl(*server_socket_desc_ptr, F_SETFL, flags) != 0 ) { printf("ERROR: OpenSocketServer(): Failed to set 'fcntl' flags to non-blocking!\n"); fflush(stdout); exit(EXIT_FAILURE); } } // Prepare the sockaddr_in structure for the server server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(server_IP); server_addr.sin_port = htons(port_number); memset(server_addr.sin_zero, 0, 8); // Bind the server with the socket. if ( bind(*server_socket_desc_ptr, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0 ) { printf("ERROR: OpenSocketServer(): Failed to bind!\n"); fflush(stdout); exit(EXIT_FAILURE); } // printf("OpenSocketServer(): Bind done!\n"); fflush(stdout); // Listen to the socket. 'queue_size' indicates how many requests can be pending before an error is // returned to the remote computer requesting a connection. listen(*server_socket_desc_ptr, queue_size); } // printf("OpenSocketServer(): Waiting for incoming connections from clients ....\n"); fflush(stdout); // Waiting and accept incoming connection from the client. Token address information is returned // Note: you can also use 'select' here to determine if a connection request exists. sizeof_sock = sizeof(struct sockaddr_in); if ( check_and_return == 0 ) { while ( (*client_socket_desc_ptr = accept(*server_socket_desc_ptr, (struct sockaddr *)client_addr_ptr, (socklen_t*)&sizeof_sock)) < 0 ) ; // if (*client_socket_desc_ptr < 0) // { printf("ERROR: OpenSocketServer(): Failed accept\n"); fflush(stdout); exit(EXIT_FAILURE); } // printf("OpenSocketServer(): Connection accepted!\n"); fflush(stdout); return 1; } else { if ( (*client_socket_desc_ptr = accept(*server_socket_desc_ptr, (struct sockaddr *)client_addr_ptr, (socklen_t*)&sizeof_sock)) < 0 ) return 0; else return 1; } return 1; } // ======================================================================================================== // ======================================================================================================== // Open the socket to the server. void OpenSocketClient(int str_length, char server_IP[str_length], int port_number, int *server_socket_desc_ptr) { struct sockaddr_in server_addr; // printf("OpenSocketClient(): Creating a socket\n"); fflush(stdout); if ( (*server_socket_desc_ptr = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { printf("ERROR: OpenSocketClient(): Could not create socket"); fflush(stdout); } server_addr.sin_addr.s_addr = inet_addr(server_IP); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port_number); memset(server_addr.sin_zero, 0, 8); // Connect to it. if ( connect(*server_socket_desc_ptr, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 ) { printf("ERROR: OpenSocketClient: Connect\n"); fflush(stdout); exit(EXIT_FAILURE); } // printf("OpenSocketClient(): Connected\n"); fflush(stdout); return; } // ======================================================================================================== // ======================================================================================================== // This function is designed to buffer data but in kernel space. It allows binary data to be transmitted. // To accomplish this, the first two bytes are interpreted as the length of the binary byte stream that follows. int SockGetB(unsigned char *buffer, int buffer_size, int socket_desc) { int tot_bytes_received, target_num_bytes; unsigned char buffer_num_bytes[3]; // Call until two bytes are returned. The 2-byte buffer represents a number that is to be interpreted as the exact // number of binary bytes that will follow in the socket. target_num_bytes = 2; tot_bytes_received = 0; while ( tot_bytes_received < target_num_bytes ) if ( (tot_bytes_received += recv(socket_desc, &buffer_num_bytes[tot_bytes_received], target_num_bytes - tot_bytes_received, 0)) < 0 ) { printf("ERROR: SockGetB(): Error in receiving two byte cnt!\n"); fflush(stdout); return -1; } // Translate the two binary bytes into an integer. target_num_bytes = (int)(buffer_num_bytes[1] << 8) + (int)buffer_num_bytes[0]; // DEBUG //printf("SockGetB(): fetching %d bytes from socket\n", target_num_bytes); fflush(stdout); // Sanity check. if ( target_num_bytes > buffer_size ) { printf("ERROR: SockGetB(): 'target_num_bytes' %d is larger than buffer input size %d\n", target_num_bytes, buffer_size); fflush(stdout); return -1; } // Now start reading binary bytes from the socket tot_bytes_received = 0; while ( tot_bytes_received < target_num_bytes ) if ( (tot_bytes_received += recv(socket_desc, &buffer[tot_bytes_received], target_num_bytes - tot_bytes_received, 0)) < 0 ) { printf("ERROR: SockGetB(): Error in receiving transmitted data!\n"); fflush(stdout); return -1; } // Sanity check if ( tot_bytes_received != target_num_bytes ) { printf("ERROR: SockGetB(): Read more bytes then requested -- 'tot_bytes_received' %d is larger than target %d\n", tot_bytes_received, target_num_bytes); fflush(stdout); return -1; } // DEBUG //printf("SockGetB(): received %d bytes\n", tot_bytes_received); fflush(stdout); return tot_bytes_received; } // ======================================================================================================== // ======================================================================================================== // This function sends binary or ASCII data of 'buffer_size' unsigned characters through the socket. It first // sends two binary bytes that represent the length of the binary or ASCII byte stream that follows. int SockSendB(unsigned char *buffer, int buffer_size, int socket_desc) { unsigned char num_bytes[2]; // Sanity check. Don't yet support transfers larger than 65,536 bytes. if ( buffer_size > 65535 ) { printf("ERROR: SockSendB(): Size of buffer %d larger than max (65536)!\n", buffer_size); fflush(stdout); return -1; } num_bytes[1] = (unsigned char)((buffer_size & 0x0000FF00) >> 8); num_bytes[0] = (unsigned char)(buffer_size & 0x000000FF); if ( send(socket_desc, num_bytes, 2, 0) < 0 ) { printf("ERROR: SockSendB(): Send 'num_bytes' %d failed\n", buffer_size); fflush(stdout); return -1; } if ( send(socket_desc, buffer, buffer_size, 0) < 0 ) { printf("ERROR: SockSendB(): Send failed\n"); fflush(stdout); return -1; } return 0; } // ======================================================================================================== // ======================================================================================================== // This function prints a header followed by a block of hex digits. Used in DEBUG mode. void PrintHeaderAndHexVals(int max_string_len, char header_str[max_string_len], int max_vals, int num_vals, unsigned char vals[max_vals], int max_vals_per_row) { int i; printf("%s", header_str); printf("\t\t"); for ( i = 0; i < num_vals; i++ ) { printf("%02X ", vals[i]); if ( (i+1) % max_vals_per_row == 0 ) printf("\n\t\t"); } // printf("\n\t\tThis last byte may have additional bits if non-zero (given left-to-right) %02X\n", vals[num_vals]); printf("\n\n"); fflush(stdout); return; }