+ new->sock_option = opt;
+ new->sock_level = lev;
+ new->opt_name = para_strdup(name);
+
+ if (val == NULL) {
+ new->opt_val = NULL;
+ new->opt_len = 0;
+ } else {
+ new->opt_val = para_malloc(len);
+ new->opt_len = len;
+ memcpy(new->opt_val, val, len);
+ }
+
+ list_add_tail(&new->node, &fo->sockopts);
+}
+
+/** Set the entire bunch of pre-connection options at once. */
+static void flowopt_setopts(int sockfd, struct flowopts *fo)
+{
+ struct pre_conn_opt *pc;
+
+ if (fo == NULL)
+ return;
+
+ list_for_each_entry(pc, &fo->sockopts, node)
+ if (setsockopt(sockfd, pc->sock_level, pc->sock_option,
+ pc->opt_val, pc->opt_len) < 0) {
+ PARA_EMERG_LOG("Can not set %s socket option: %s",
+ pc->opt_name, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+}
+
+/**
+ * Deallocate all resources of a flowopts structure.
+ *
+ * \param fo A pointer as returned from flowopt_new().
+ *
+ * It's OK to pass \p NULL here in which case the function does nothing.
+ */
+void flowopt_cleanup(struct flowopts *fo)
+{
+ struct pre_conn_opt *cur, *next;
+
+ if (fo == NULL)
+ return;
+
+ list_for_each_entry_safe(cur, next, &fo->sockopts, node) {
+ free(cur->opt_name);
+ free(cur->opt_val);
+ free(cur);
+ }
+ free(fo);
+}
+
+/**
+ * Resolve an IPv4/IPv6 address.
+ *
+ * \param l4type The layer-4 type (\p IPPROTO_xxx).
+ * \param passive Whether \p AI_PASSIVE should be included as hint.
+ * \param host Remote or local hostname or IPv/6 address string.
+ * \param port_number Used to set the port in each returned address structure.
+ * \param result addrinfo structures are returned here.
+ *
+ * The interpretation of \a host depends on the value of \a passive. On a
+ * passive socket host is interpreted as an interface IPv4/6 address (can be
+ * left NULL). On an active socket, \a host is the peer DNS name or IPv4/6
+ * address to connect to.
+ *
+ * \return Standard.
+ *
+ * \sa getaddrinfo(3).
+ */
+int lookup_address(unsigned l4type, bool passive, const char *host,
+ int port_number, struct addrinfo **result)
+{
+ int ret;
+ char port[6]; /* port number has at most 5 digits */
+ struct addrinfo *addr = NULL, hints;
+
+ *result = NULL;
+ sprintf(port, "%u", port_number & 0xffff);
+ /* Set up address hint structure */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = sock_type(l4type);