void minisocket_close(minisocket_t *socket) { if (socket) { if (socket->socket_state == CLOSING) { socket->socket_state = WAITING_SYN; return; } if (socket->socket_state == CLOSED) { minisocket_free(socket); return; } minisocket_error s_error; int wait_val = 100; while (wait_val <= 12800) { send_control_message(MSG_FIN, socket->remote_port, socket->remote_addr, socket->local_port, socket->seq_number, socket->ack_number, &s_error); socket->seq_number += 1; if (s_error == SOCKET_OUTOFMEMORY) { return; } alarm_id a = register_alarm(wait_val, (alarm_handler_t) semaphore_V, socket->wait_for_ack); semaphore_P(socket->wait_for_ack); interrupt_level_t old_level = set_interrupt_level(DISABLED); if (socket->ack_flag == 0) { wait_val *= 2; socket->seq_number--; set_interrupt_level(old_level); continue; } else if (socket->ack_flag == 1) { deregister_alarm(a); minisocket_free(socket); set_interrupt_level(old_level); return; } } } semaphore_V(socket->send_receive_mutex); }
static int control_channel_handler(int connfd) { char *password; data_endpoint_t *ep; sslutil_connection_t ssl_conn; linfo("Connection handler started. Initiating SSL handshake."); ssl_conn = sslutil_connect(connfd, server); if (ssl_conn == 0) { linfo("Unable to start SSL session"); return EXIT_SSL_ERROR; } if (!ivpn_protocol_handshake(ssl_conn)) return EXIT_PROTO_ERROR; linfo ("IVPN Protocol handshake completed successfully."); ep = start_data_endpoint(NULL); assert(ep != 0); if (relinquish_superuser(NULL) == 0) { lerr("Unable to relinquish privileges. Quitting."); return EXIT_FAILURE; } usleep(100000); // 100 ms password = get_password("Password:"******"Authentication failed."); return EXIT_AUTH_ERROR; } memset(password, 0, strlen(password)); // clear plain text password linfo ("Authenticated with server. Data port is %u", ep->peer_port); ep->peer_ip = inet_addr(get_ip_from_name(server)); if (write(ep->write_fd, &ep->peer_ip, sizeof(ep->peer_ip)) == -1 || write(ep->write_fd, &ep->peer_port, sizeof(ep->peer_port)) == -1) { lerr("Unable to write to UDP process pipe. Quitting.", strerror(errno)); return EXIT_FAILURE; } usleep(100000); // 100 ms while (1) { char command[64]; fprintf(stdout, "ivpn> "); fflush(stdout); if (fgets(command, sizeof(command) - 1, stdin) == 0) { linfo("End of input. Terminating..."); break; } if (strcmp(command, "quit\n") == 0) { linfo("Quit command. Terminating..."); break; } if (strcmp(command, "changekey\n") == 0) { char key[IVPN_KEY_LENGTH]; linfo("Performing key change."); generate_true_random(key, sizeof(key)); /* send key to local UDP process first */ if (write(ep->write_fd, key, sizeof(key)) != sizeof(key)) { lerr("Unable to send key to local UDP process : %s. Quitting...", strerror(errno)); break; } else { linfo("New key sent to local UDP process"); } /* send key to VPN server */ cm_setkey_t *cm = create_cm_setkey(key); if (cm == 0) { lerr ("Unable to generate command for sending to VPN server. Quitting..."); break; } if (send_control_message(ssl_conn, (cm_header_t *)cm) == 0) { lerr ("Unable to sending command to VPN server. Quitting..."); break; } cm_header_t *rsp = recv_control_message(ssl_conn); if (rsp == 0) { lerr ("Unable to receive command from VPN server. Quitting..."); break; } if (rsp->cm_type == CM_TYPE_OK) { linfo("Setting new key in server succeeded"); } else { lerr("Setting new key in server failed. Quitting..."); break; } } } return 0; }
minisocket_t* minisocket_server_create(int port, minisocket_error *error) { if (port < MIN_SERVER_PORT || port > MAX_SERVER_PORT) { *error = SOCKET_INVALIDPARAMS; return NULL; } if (ports[port]) { *error = SOCKET_PORTINUSE; return NULL; } minisocket_t *new_socket = (minisocket_t *) malloc(sizeof(minisocket_t)); if (!new_socket) { *error = SOCKET_OUTOFMEMORY; return NULL; } // Initialize new socket new_socket->socket_state = INITIAL; semaphore_P(ports_mutex); ports[port] = new_socket; semaphore_V(ports_mutex); new_socket->socket_type = 's'; new_socket->local_port = port; network_address_copy(local_host, new_socket->local_addr); new_socket->data = queue_new(); new_socket->data_ready = semaphore_create(); new_socket->ack_flag = 0; new_socket->wait_for_ack = semaphore_create(); new_socket->send_receive_mutex = semaphore_create(); semaphore_initialize(new_socket->data_ready, 0); semaphore_initialize(new_socket->wait_for_ack, 0); semaphore_initialize(new_socket->send_receive_mutex, 1); interrupt_level_t old_level; while (1) { new_socket->seq_number = 0; new_socket->ack_number = 0; new_socket->remote_port = -1; new_socket->remote_addr[0] = 0; new_socket->remote_addr[1] = 0; new_socket->socket_state = WAITING_SYN; // receiving SYN while (1) { semaphore_P(new_socket->data_ready); network_interrupt_arg_t *arg = NULL; queue_dequeue(new_socket->data, (void **) &arg); mini_header_reliable_t *header = (mini_header_reliable_t *) arg->buffer; if (header->message_type -'0'== MSG_SYN) { unpack_address(header->source_address, new_socket->remote_addr); new_socket->remote_port = unpack_unsigned_short(header->source_port); new_socket->socket_state = WAITING_ACK; new_socket->seq_number = 0; new_socket->ack_number = 1; break; } else { free(arg); } } minisocket_error s_error; int wait_val = 100; while (wait_val <= 12800) { send_control_message(MSG_SYNACK, new_socket->remote_port, new_socket->remote_addr, new_socket->local_port, 0 , 1, &s_error); new_socket->seq_number = 1; new_socket->ack_number = 1; if (s_error == SOCKET_OUTOFMEMORY) { minisocket_free(new_socket); semaphore_P(ports_mutex); ports[new_socket->local_port] = NULL; semaphore_V(ports_mutex); *error = s_error; return NULL; } alarm_id a = register_alarm(wait_val, (alarm_handler_t) semaphore_V, new_socket->data_ready); semaphore_P(new_socket->data_ready); old_level = set_interrupt_level(DISABLED); if (queue_length(new_socket->data)) { deregister_alarm(a); } set_interrupt_level(old_level); if (!queue_length(new_socket->data)) { wait_val *= 2; continue; } network_interrupt_arg_t *arg = NULL; queue_dequeue(new_socket->data, (void **) &arg); mini_header_reliable_t *header = (mini_header_reliable_t *) arg->buffer; network_address_t saddr; unpack_address(header->source_address, saddr); int sport = unpack_unsigned_short(header->source_port); if (header->message_type - '0' == MSG_SYN) { if (new_socket->remote_port == sport && network_compare_network_addresses(new_socket->remote_addr, saddr)) { continue; } send_control_message(MSG_FIN, sport, saddr, new_socket->local_port, 0, 0, &s_error); } if (header->message_type - '0' == MSG_ACK) { if (new_socket->remote_port == sport && network_compare_network_addresses(new_socket->remote_addr, saddr)) { network_interrupt_arg_t *packet = NULL; while (queue_dequeue(new_socket->data, (void **)&packet) != -1) { free(packet); } semaphore_initialize(new_socket->data_ready, 0); new_socket->socket_state = OPEN; new_socket->seq_number = 1; new_socket->ack_number = 2; return new_socket; } } free (arg); } } return NULL; }
void minisocket_handle_tcp_packet(network_interrupt_arg_t *arg) { mini_header_reliable_t *header = (mini_header_reliable_t *) (arg->buffer); int port = unpack_unsigned_short(header->destination_port); if (port < MIN_SERVER_PORT || port > MAX_CLIENT_PORT || !ports[port]) { free(arg); return; } if (ports[port]->socket_state == INITIAL || ports[port]->socket_state == CLOSED) { free(arg); return; } if (ports[port]->socket_state != OPEN) { // handled in handshake queue_append(ports[port]->data, arg); semaphore_V(ports[port]->data_ready); return; } minisocket_error s_error; network_address_t saddr; unpack_address(header->source_address, saddr); int sport = unpack_unsigned_short(header->source_port); if (!network_compare_network_addresses(ports[port]->remote_addr, saddr) || ports[port]->remote_port != sport) { if(header->message_type -'0' == MSG_SYN) { send_control_message(MSG_FIN, sport, saddr, port, 0, 0, &s_error); } free(arg); return; } //If the message is of type SYNACK and from the same client if (header->message_type - '0' == MSG_SYNACK) { send_control_message(MSG_ACK, sport, saddr, port, 0, 0, &s_error); free(arg); return; } //If the message is of type FIN if (header->message_type - '0' == MSG_FIN) { ports[port]->ack_number += 1; send_control_message(MSG_ACK, sport, saddr, port, ports[port]->seq_number, ports[port]->ack_number, &s_error); ports[port]->socket_state = CLOSING; int count = semaphore_get_count(ports[port]->data_ready); while (count < 0) { semaphore_V(ports[port]->data_ready); count++; } register_alarm(15000, (alarm_handler_t) minisocket_close, ports[port]); //minisocket_free(ports[port]); free(arg); return; } //If the message is of type ACK from the same client if (header->message_type - '0' == MSG_ACK) { unsigned int ack_no = unpack_unsigned_int(header->ack_number); int packet_size = arg->size - sizeof(mini_header_reliable_t); minisocket_error s_error; //If it's a correct acknowledgement of the sent data, enqueue it and V the wait for ack semaphore if (ack_no == ports[port]->seq_number/* + MAX_NETWORK_PKT_SIZE - sizeof(mini_header_reliable_t) + 1*/) { if (packet_size != 0) { queue_append(ports[port]->data, arg); semaphore_V(ports[port]->data_ready); ports[port]->ack_number += packet_size; send_control_message(MSG_ACK, sport, saddr, port, ports[port]->seq_number, ports[port]->ack_number, &s_error); } if (ports[port]->ack_flag == 0) { ports[port]->ack_flag = 1; semaphore_V(ports[port]->wait_for_ack); } return; } else { free(arg); return; } } }
minisocket_t* minisocket_client_create(const network_address_t addr, int port, minisocket_error *error) { if (!addr || port < MIN_SERVER_PORT || port > MAX_SERVER_PORT) { *error = SOCKET_INVALIDPARAMS; return NULL; } int port_val = -1; // CHECK what n_client_ports does if (!ports[n_client_ports]) { port_val = n_client_ports; } else { for (int i = MIN_CLIENT_PORT; i <= MAX_CLIENT_PORT; i++) { if (!ports[i]) { port_val = i; break; } } } n_client_ports = port_val + 1; if (n_client_ports > MAX_CLIENT_PORT) { n_client_ports = 0; } if (port_val == -1) { *error = SOCKET_NOMOREPORTS; return NULL; } minisocket_t *new_socket = (minisocket_t *) malloc(sizeof(minisocket_t)); if (!new_socket) { *error = SOCKET_OUTOFMEMORY; return NULL; } new_socket->socket_state = INITIAL; semaphore_P(ports_mutex); ports[port_val] = new_socket; semaphore_V(ports_mutex); new_socket->socket_type = 'c'; network_address_copy(local_host, new_socket->local_addr); //network_get_my_address(new_socket->local_addr); new_socket->local_port = port_val; network_address_copy(addr, new_socket->remote_addr); new_socket->remote_port = port; new_socket->data = queue_new(); new_socket->data_ready = semaphore_create(); new_socket->wait_for_ack = semaphore_create(); new_socket->send_receive_mutex = semaphore_create(); semaphore_initialize(new_socket->data_ready, 0); semaphore_initialize(new_socket->wait_for_ack, 0); semaphore_initialize(new_socket->send_receive_mutex, 1); new_socket->socket_state = WAITING_SYNACK; minisocket_error s_error; int wait_val = 100; interrupt_level_t old_level; while (wait_val <= 12800) { send_control_message(MSG_SYN, new_socket->remote_port, new_socket->remote_addr, new_socket->local_port, 0, 0, &s_error); new_socket->seq_number = 1; new_socket->ack_number = 0; if (s_error == SOCKET_OUTOFMEMORY) { minisocket_free(new_socket); semaphore_P(ports_mutex); ports[new_socket->local_port] = NULL; semaphore_V(ports_mutex); *error = s_error; return NULL; } alarm_id a = register_alarm(wait_val, (alarm_handler_t) semaphore_V, new_socket->data_ready); semaphore_P(new_socket->data_ready); old_level = set_interrupt_level(DISABLED); if (queue_length(new_socket->data)) { deregister_alarm(a); } set_interrupt_level(old_level); if (!queue_length(new_socket->data)) { wait_val *= 2; continue; } network_interrupt_arg_t *arg = NULL; queue_dequeue(new_socket->data, (void **) &arg); mini_header_reliable_t *header = (mini_header_reliable_t *) arg->buffer; network_address_t saddr; unpack_address(header->source_address, saddr); int sport = unpack_unsigned_short(header->source_port); if (sport == new_socket->remote_port && network_compare_network_addresses(saddr, new_socket->remote_addr)) { if (header->message_type - '0' == MSG_SYNACK) { new_socket->seq_number = 1; new_socket->ack_number = 1; send_control_message(MSG_ACK, new_socket->remote_port, new_socket->remote_addr, new_socket->local_port, 1, 1, &s_error); if (s_error == SOCKET_OUTOFMEMORY) { minisocket_free(new_socket); semaphore_P(ports_mutex); ports[new_socket->local_port] = NULL; semaphore_V(ports_mutex); *error = s_error; return NULL; } network_interrupt_arg_t *packet = NULL; while (queue_dequeue(new_socket->data, (void **)&packet) != -1) { free(packet); } semaphore_initialize(new_socket->data_ready, 0); new_socket->socket_state = OPEN; new_socket->seq_number = 2; new_socket->ack_number = 1; return new_socket; } if (header->message_type -'0' == MSG_FIN) { minisocket_free(new_socket); return NULL; } } free(arg); } minisocket_free(new_socket); return NULL; }