Example #1
0
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);
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
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;
    }
  }
}
Example #5
0
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;
}