static void set_keepalive(int rs) { int optval; socklen_t optlen = sizeof(optlen); optval = 1; if (rs_setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)) { perror("rsetsockopt SO_KEEPALIVE"); return; } optval = keepalive; if (rs_setsockopt(rs, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen)) perror("rsetsockopt TCP_KEEPIDLE"); if (!(rs_getsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen))) printf("Keepalive: %s\n", (optval ? "ON" : "OFF")); if (!(rs_getsockopt(rs, IPPROTO_TCP, TCP_KEEPIDLE, &optval, &optlen))) printf(" time: %i\n", optval); }
static int client_connect(void) { struct rdma_addrinfo *rai = NULL; struct addrinfo *ai; struct pollfd fds; int ret, err; socklen_t len; ret = use_rgai ? rdma_getaddrinfo(dst_addr, port, &rai_hints, &rai) : getaddrinfo(dst_addr, port, &ai_hints, &ai); if (ret) { perror("getaddrinfo"); return ret; } rs = rai ? rs_socket(rai->ai_family, SOCK_STREAM, 0) : rs_socket(ai->ai_family, SOCK_STREAM, 0); if (rs < 0) { perror("rsocket"); ret = rs; goto free; } set_options(rs); /* TODO: bind client to src_addr */ if (rai && rai->ai_route) { ret = rs_setsockopt(rs, SOL_RDMA, RDMA_ROUTE, rai->ai_route, rai->ai_route_len); if (ret) { perror("rsetsockopt RDMA_ROUTE"); goto close; } } ret = rai ? rs_connect(rs, rai->ai_dst_addr, rai->ai_dst_len) : rs_connect(rs, ai->ai_addr, ai->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 = rs_getsockopt(rs, SOL_SOCKET, SO_ERROR, &err, &len); if (ret) goto close; if (err) { ret = -1; errno = err; perror("async rconnect"); } } close: if (ret) rs_close(rs); free: if (rai) rdma_freeaddrinfo(rai); else freeaddrinfo(ai); return ret; }