/**
	@brief Report whether a transport_client is connected.
	@param client Pointer to the transport_client.
	@return Boolean: 1 if connected, or 0 if not.
*/
int client_connected( const transport_client* client ) {
	if(client == NULL) return 0;
	return session_connected( client->session );
}
Example #2
0
static void global_cb(EV_P_ ev_io *w, int revents) {
  global_context *gc = (global_context *)w->data;
  static int count = 0;
  int ret = 0;
  struct sockaddr_storage local_addr;
  socklen_t local_addr_size = sizeof(local_addr);

  log_debug("global_cb fds: %d,%d revents: 0x%02x count: %d", w->fd, gc->listen_fd.fd, revents, count);
  count++;

  ret = getsockname(gc->listen_fd.fd, (struct sockaddr *)&local_addr, &local_addr_size);
  if (ret < 0) {
    log_error("getsockname() failed errno=%d", ret, errno);
    return;
  }

  /* Read all the incoming packets waiting on listen_fd, and create a session for each one */
  for (;;) {
    mbedtls_net_context client_fd;
    session_context *sc;
    struct sockaddr_storage client_addr;
    socklen_t client_addr_size = sizeof(client_addr);
    unsigned char first_packet[MBEDTLS_SSL_MAX_CONTENT_LEN];
    size_t first_packet_len = 0;

    ret = recvfrom(gc->listen_fd.fd, first_packet, sizeof(first_packet), 0,
                   (struct sockaddr *)&client_addr, &client_addr_size);
    if (ret < 0) {
      int save_errno = errno;
      if ((save_errno == EAGAIN) || (save_errno == EWOULDBLOCK)) {
        /* We finished reading everything that was available so far */
        return;
      }
      log_error("recvfrom failed on listening socket (fd=%d), errno=%d", gc->listen_fd.fd,
                save_errno);
      return;
    } else if (ret == 0) {
      log_error("recvfrom() returned 0, this shouldn't happen");
      continue;
    }

    first_packet_len = ret;

    /* We have a new client! Connect the client_fd socket to that peer */
    ret = connect_to_new_client(&client_fd,
                                &client_addr, client_addr_size,
                                &local_addr, local_addr_size);
    if (ret != 0) {
      log_error("connect_to_new_client failed");
      continue;
    }

    if (active_session_context != NULL) {
        session_free(EV_A_ active_session_context);
        active_session_context = NULL;        
    }

    sc = calloc(1, sizeof(session_context));

    session_init(gc, sc, &client_fd, (unsigned char *)&client_addr, client_addr_size,
                 first_packet, first_packet_len);

    if (session_connected(sc) != 0) {
      log_error("can't init client connection");
      free(sc);
      continue;
    }

    active_session_context = sc;
    
    /* Start listening for network events on the new client fd */
    session_start(sc, EV_A);
    log_debug("global_cb - session_start - client_fd %d", sc->client_fd.fd);

    /* Trigger the FSM drive and start DTLS negotiation to backend, and 
     * during this time, we just silently drop the first packet from 
     * vpn client.
     */
    ev_feed_fd_event(EV_A_ sc->backend_fd.fd, EV_READ);
  }
}