int getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen) { int fd; return (fd_get(socket, &fd) == fd_rsocket) ? rgetsockopt(fd, level, optname, optval, optlen) : real.getsockopt(fd, level, optname, optval, optlen); }
static int client_connect(void) { struct addrinfo *res; struct pollfd fds; int ret, err; socklen_t len; ret = getaddrinfo(dst_addr, port, NULL, &res); if (ret) { perror("getaddrinfo"); return ret; } rs = rsocket(res->ai_family, res->ai_socktype, res->ai_protocol); if (rs < 0) { perror("rsocket"); ret = rs; goto free; } set_options(rs); /* TODO: bind client to src_addr */ ret = rconnect(rs, res->ai_addr, res->ai_addrlen); if (ret && (errno != EINPROGRESS)) { perror("rconnect"); goto close; } if (ret && (errno == EINPROGRESS)) { fds.fd = rs; fds.events = POLLOUT; ret = do_poll(&fds, poll_timeout); if (ret) goto close; len = sizeof err; ret = rgetsockopt(rs, SOL_SOCKET, SO_ERROR, &err, &len); if (ret) goto close; if (err) { ret = -1; errno = err; perror("async rconnect"); } } close: if (ret) rclose(rs); free: freeaddrinfo(res); return ret; }