/* * Open the UNIX domain socket * * Returns the file descriptor if successful, or -1 if failed */ static twopence_sock_t * __twopence_virtio_open(struct twopence_pipe_target *pipe_handle) { struct twopence_virtio_target *handle = (struct twopence_virtio_target *) pipe_handle; int socket_fd; // Create the file descriptor socket_fd = socket(PF_LOCAL, SOCK_STREAM, AF_UNIX); if (socket_fd <= 0) return NULL; // Open the connection if (connect(socket_fd, (const struct sockaddr *) &handle->address, sizeof(struct sockaddr_un))) { close(socket_fd); return NULL; } /* Note, we do not pass O_NONBLOCK here, but we do set O_CLOEXEC */ return twopence_sock_new_flags(socket_fd, O_RDWR | O_CLOEXEC); }
/* * Open the TCP socket * * Returns the file descriptor if successful, or -1 if failed */ static twopence_sock_t * __twopence_tcp_open(struct twopence_pipe_target *pipe_handle) { struct twopence_tcp_target *handle = (struct twopence_tcp_target *) pipe_handle; char *copy, *hostname, *portname = NULL; struct addrinfo hints; struct addrinfo *ai_list, *ai; int socket_fd = -1; int res; copy = hostname = twopence_strdup(handle->server_spec); if (hostname[0] == '[') { /* Something like [::1] */ char *s; for (s = ++hostname; *s != ']'; ++s) { if (*s == '\0') { twopence_log_error("tcp: cannot parse \"%s\"", handle->server_spec); free(copy); return NULL; } } *s++ = '\0'; if (*s == ':') portname = ++s; /* Any other garbage is silently ignored for now */ } else if ((portname = strchr(hostname, ':')) != NULL) *portname++ = '\0'; if (portname == NULL) portname = TWOPENCE_TCP_PORT_DEFAULT_STR; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; res = getaddrinfo(hostname, portname, &hints, &ai_list); free(copy); copy = hostname = portname = NULL; if (res != 0) { twopence_log_error("tcp: cannot resolve \"%s\": %s", handle->server_spec, gai_strerror(res)); return NULL; } twopence_debug("trying to open connection to %s", handle->server_spec); for (ai = ai_list; ai && socket_fd < 0; ai = ai->ai_next) { socket_fd = socket(ai->ai_family, SOCK_STREAM, 0); if (socket_fd <= 0) break; // Open the connection if (connect(socket_fd, ai->ai_addr, ai->ai_addrlen) < 0) { /* Okay, this address didn't work. Try the next one */ close(socket_fd); socket_fd = -1; } } freeaddrinfo(ai_list); if (socket_fd <= 0) return NULL; /* Note, we do not pass O_NONBLOCK here, but we do set O_CLOEXEC */ return twopence_sock_new_flags(socket_fd, O_RDWR | O_CLOEXEC); }