+ {
+ int err;
+ socklen_t errlen = sizeof(err);
+ char *errmsg = NULL;
+ if (getsockopt(s->s, SOL_SOCKET, SO_ERROR, &err, &errlen)<0) {
+ errmsg = dupprintf("getsockopt(SO_ERROR): %s",
+ strerror(errno));
+ err = errno; /* got to put something in here */
+ } else if (err != 0) {
+ errmsg = dupstr(strerror(err));
+ }
+ if (errmsg) {
+ /*
+ * The asynchronous connection attempt failed.
+ * Report the problem via plug_log, and try again
+ * with the next candidate address, if we have
+ * more than one.
+ */
+ struct SockAddr_tag thisaddr;
+ assert(s->addr);
+
+ thisaddr = sk_extractaddr_tmp(s->addr, &s->step);
+ plug_log(s->plug, 1, &thisaddr, s->port, errmsg, err);
+
+ while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
+ err = try_connect(s);
+ }
+ if (err)
+ return plug_closing(s->plug, strerror(err), err, 0);
+ if (!s->connected)
+ return 0; /* another async attempt in progress */
+ }
+ }
+
+ /*
+ * If we get here, we've managed to make a connection.
+ */
+ if (s->addr) {
+ sk_addr_free(s->addr);
+ s->addr = NULL;
+ }