if (var)
sq_inline = atoi(var);
- var = getenv("RS_FORK");
+ var = getenv("RDMAV_FORK_SAFE");
if (var)
fork_support = atoi(var);
}
return ret;
}
+/*
+ * Convert between an rsocket and a normal socket. The new socket should have the
+ * same settings and bindings as the current socket. We currently only handle
+ * setting a few of the more common values.
+ */
+static int
+transpose_socket(int index, int *fd, enum fd_type new_type,
+ int (*socket_new)(int domain, int type, int protocol),
+ int (*shutdown_old)(int socket, int how),
+ int (*close_old)(int socket),
+ int (*getsockname_old)(int socket, struct sockaddr *addr,
+ socklen_t *addrlen),
+ int (*getsockopt_old)(int socket, int level, int optname,
+ void *optval, socklen_t *optlen),
+ int (*setsockopt_new)(int socket, int level, int optname,
+ const void *optval, socklen_t optlen),
+ int (*fcntl_old)(int socket, int cmd, ... /* arg */),
+ int (*fcntl_new)(int socket, int cmd, ... /* arg */))
+{
+ socklen_t len = 0;
+ int new_fd, param, ret;
+
+ ret = getsockname_old(*fd, NULL, &len);
+ if (ret)
+ return ret;
+
+ param = (len == sizeof(struct sockaddr_in6)) ? PF_INET6 : PF_INET;
+ new_fd = socket_new(param, SOCK_STREAM, 0);
+ if (new_fd < 0)
+ return new_fd;
+
+ ret = fcntl_old(*fd, F_GETFL);
+ if (ret > 0)
+ ret = fcntl_new(new_fd, F_SETFL, ret);
+ if (ret)
+ goto err;
+
+ len = sizeof param;
+ ret = getsockopt_old(*fd, SOL_SOCKET, SO_REUSEADDR, ¶m, &len);
+ if (param && !ret)
+ ret = setsockopt_new(new_fd, SOL_SOCKET, SO_REUSEADDR, ¶m, len);
+ if (ret)
+ goto err;
+
+ len = sizeof param;
+ ret = getsockopt_old(*fd, IPPROTO_TCP, TCP_NODELAY, ¶m, &len);
+ if (param && !ret)
+ ret = setsockopt_new(new_fd, IPPROTO_TCP, TCP_NODELAY, ¶m, len);
+ if (ret)
+ goto err;
+
+ shutdown_old(*fd, SHUT_RDWR);
+ close_old(*fd);
+ fd_store(socket, new_fd, new_type);
+ *fd = new_fd;
+ return 0;
+
+err:
+ real_close(new_fd);
+ return ret;
+}
+
/*
* Use defaults on failure.
*/
}
}
+static int connect_fork(int socket, const struct sockaddr *addr, socklen_t addrlen)
+{
+ uint32_t msg;
+ int rs, fd, ret;
+
+ fd = fd_getd(socket);
+ ret = real_connect(fd, addr, addrlen);
+ if (!ret)
+ return ret;
+
+ ret = real_read(fd, &msg, sizeof msg);
+ if (ret != sizeof msg)
+ return ret;
+
+ rs = rsocket(domain, type, protocol);
+
+ real_shutdown(fd, SHUT_RDWR);
+ real_close(fd);
+
+ fd_store(socket, fd, fd_rsocket);
+ return connect(socket, addr, addrlen);
+}
+
int connect(int socket, const struct sockaddr *addr, socklen_t addrlen)
{
struct sockaddr_in *sin;