- if ((rc = getaddrinfo(host, port, &hints, passive ? &local : &remote))) {
- PARA_ERROR_LOG("can not resolve %s address %s#%s: %s.\n",
- layer4_name(l4type),
- host? host : (passive? "[loopback]" : "[localhost]"),
- port, gai_strerror(rc));
- rc = -E_ADDRESS_LOOKUP;
- goto out;
+ ret = getaddrinfo(host, port, &hints, &addr);
+ if (ret != 0) {
+ PARA_ERROR_LOG("can not resolve %s address %s#%s: %s\n",
+ layer4_name(l4type),
+ host? host : (passive? "[loopback]" : "[localhost]"),
+ port, gai_strerror(ret));
+ return -E_ADDRESS_LOOKUP;
+ }
+ *result = addr;
+ return 1;
+}
+
+/*
+ * Create an active or passive socket.
+ *
+ * \param l4type \p IPPROTO_TCP, \p IPPROTO_UDP, or \p IPPROTO_DCCP.
+ * \param passive Whether to call bind(2) or connect(2).
+ * \param ai Address information as obtained from \ref lookup_address().
+ * \param fo Socket options to be set before making the connection.
+ *
+ * bind(2) is called on passive sockets, and connect(2) on active sockets. The
+ * algorithm tries all possible address combinations until it succeeds. If \a
+ * fo is supplied, options are set and cleanup is performed.
+ *
+ * \return File descriptor on success, \p E_MAKESOCK on errors.
+ *
+ * \sa \ref lookup_address(), \ref makesock(), ip(7), ipv6(7), bind(2),
+ * connect(2).
+ */
+static int makesock_addrinfo(unsigned l4type, bool passive, struct addrinfo *ai,
+ struct flowopts *fo)
+{
+ struct addrinfo *local, *remote, *src = NULL, *dst = NULL;
+ int rc = -E_MAKESOCK, on = 1, sockfd = -1;
+
+ if (passive) {
+ local = ai;
+ remote = NULL;
+ } else {
+ local = NULL;
+ remote = ai;