+ memcpy(&c->address, outgoing->aip->ai_addr, outgoing->aip->ai_addrlen);
+
+ char *hostname = sockaddr2hostname(&c->address);
+
+ logger(mesh, MESHLINK_INFO, "Trying to connect to %s at %s", outgoing->node->name, hostname);
+
+ if(!mesh->proxytype) {
+ c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+ configure_tcp(c);
+ } else {
+ proxyai = str2addrinfo(mesh->proxyhost, mesh->proxyport, SOCK_STREAM);
+
+ if(!proxyai) {
+ free_connection(c);
+ free(hostname);
+ goto begin;
+ }
+
+ logger(mesh, MESHLINK_INFO, "Using proxy at %s port %s", mesh->proxyhost, mesh->proxyport);
+ c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
+ configure_tcp(c);
+ }
+
+ if(c->socket == -1) {
+ logger(mesh, MESHLINK_ERROR, "Creating socket for %s at %s failed: %s", c->name, hostname, sockstrerror(sockerrno));
+ free_connection(c);
+ free(hostname);
+ goto begin;
+ }
+
+ free(hostname);
+
+#ifdef FD_CLOEXEC
+ fcntl(c->socket, F_SETFD, FD_CLOEXEC);
+#endif
+
+#if defined(IPV6_V6ONLY)
+
+ if(c->address.sa.sa_family == AF_INET6) {
+ static const int option = 1;
+ setsockopt(c->socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof(option));
+ }
+
+#endif
+
+ bind_to_address(mesh, c);
+
+ /* Connect */
+
+ if(!mesh->proxytype) {
+ result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
+ } else {
+ result = connect(c->socket, proxyai->ai_addr, proxyai->ai_addrlen);
+ freeaddrinfo(proxyai);
+ }
+
+ if(result == -1 && !sockinprogress(sockerrno)) {
+ logger(mesh, MESHLINK_ERROR, "Could not connect to %s: %s", outgoing->node->name, sockstrerror(sockerrno));
+ free_connection(c);
+
+ goto begin;
+ }
+
+ /* Now that there is a working socket, fill in the rest and register this connection. */
+
+ c->status.connecting = true;
+ c->status.initiator = true;
+ c->name = xstrdup(outgoing->node->name);
+ c->last_ping_time = mesh->loop.now.tv_sec;
+
+ connection_add(mesh, c);
+
+ io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ | IO_WRITE);