ssize_t ssl_socket_receive_all_nonblocking(void *state_data, bool *error, void *data_, size_t size) { struct ssl_state *state = (struct ssl_state*)state_data; const uint8_t *data = (const uint8_t*)data_; /* mbedtls_ssl_read wants non-const data but it only reads it, so this cast is safe */ ssize_t ret; mbedtls_net_set_nonblock(&state->net_ctx); ret = mbedtls_ssl_read(&state->ctx, (unsigned char*)data, size); if (ret > 0) return ret; if (ret == 0) { /* Socket closed */ *error = true; return -1; } if (isagain((int)ret)) return 0; *error = true; return -1; }
static int connect_to_backend(session_context *sc) { int ret; ret = mbedtls_net_connect(&sc->backend_fd, sc->options->backend_host, sc->options->backend_port, MBEDTLS_NET_PROTO_UDP); if (ret != 0) { return 1; } mbedtls_net_set_nonblock(&sc->backend_fd); log_info("Created socket to backend UDP %s:%s", sc->options->backend_host, sc->options->backend_port); return 0; }
static int bind_listen_fd(global_context *gc) { int ret; ret = mbedtls_net_bind(&gc->listen_fd, gc->options->listen_host, gc->options->listen_port, MBEDTLS_NET_PROTO_UDP); if (ret != 0) { log_error("Bind failed for host %s on UDP port %s", gc->options->listen_host, gc->options->listen_port); check_return_code(ret, "bind_listen_fd"); return ret; } log_debug("Binded UDP %s:%s", gc->options->listen_host, gc->options->listen_port); mbedtls_net_set_nonblock(&gc->listen_fd); return 0; }
ssize_t ssl_socket_send_all_nonblocking(void *state_data, const void *data_, size_t size, bool no_signal) { struct ssl_state *state = (struct ssl_state*)state_data; const uint8_t *data = (const uint8_t*)data_; ssize_t sent = size; int ret; mbedtls_net_set_nonblock(&state->net_ctx); ret = mbedtls_ssl_write(&state->ctx, data, size); if (ret <= 0) return -1; return sent; }
static int connect_to_new_client(mbedtls_net_context* client_fd, const struct sockaddr_storage *client_addr, const socklen_t client_addr_size, const struct sockaddr_storage *local_addr, const socklen_t local_addr_size) { int ret = 0; int one = 1; mbedtls_net_init(client_fd); client_fd->fd = socket(client_addr->ss_family, SOCK_DGRAM, IPPROTO_UDP); if (client_fd->fd < 0) { log_error("socket() failed errno=%d", ret, errno); return 1; } #ifdef __APPLE__ // MacOS/X requires an additional call ret = setsockopt(client_fd->fd, SOL_SOCKET, SO_REUSEPORT, (char*)&one, sizeof(one)); if (ret != 0) { log_error("setsockopt(SO_REUSEPORT) failed ret=%d errno=%d", ret, errno); return 1; } #endif ret = setsockopt(client_fd->fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)); if (ret != 0) { log_error("setsockopt(SO_REUSEADDR) failed ret=%d errno=%d", ret, errno); return 1; } mbedtls_net_set_nonblock(client_fd); ret = bind(client_fd->fd, (struct sockaddr *)local_addr, local_addr_size); if (ret != 0) { log_error("bind() fd=%d failed ret=%d errno=%d", client_fd->fd, ret, errno); return 1; } ret = connect(client_fd->fd, (struct sockaddr *)client_addr, client_addr_size); if (ret != 0) { log_error("connect() failed ret=%d errno=%d", ret, errno); return 1; } log_debug("connect_to_new_client: connected on fd %d", client_fd->fd); return 0; }