/** @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 ); }
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); } }