- struct GNUNET_CLIENT_TransmitHandle *th = cls;
-
- th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
-#if DEBUG_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transmission failed due to shutdown.\n");
-#endif
- th->sock->th = NULL;
- th->notify (th->notify_cls, 0, NULL);
- GNUNET_free (th);
- return;
- }
- th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock,
- th->size,
- GNUNET_TIME_absolute_get_remaining
- (th->timeout),
- &client_notify, th);
- if (th->th == NULL)
- {
- GNUNET_break (0);
- th->notify (th->notify_cls, 0, NULL);
- GNUNET_free (th);
- return;
- }
+ struct ClientState *cstate = cls;
+ struct AddressProbe *ap;
+
+ if (NULL == addr)
+ {
+ cstate->dns_active = NULL;
+ if ( (NULL == cstate->ap_head) &&
+ // (NULL == cstate->proxy_handshake) &&
+ (NULL == cstate->sock) )
+ connect_fail_continuation (cstate);
+ return;
+ }
+ if (NULL != cstate->sock)
+ return; /* already connected */
+ /* try to connect */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to connect using address `%s:%u'\n",
+ GNUNET_a2s (addr,
+ addrlen),
+ cstate->port);
+ ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
+ ap->addr = (const struct sockaddr *) &ap[1];
+ GNUNET_memcpy (&ap[1],
+ addr,
+ addrlen);
+ ap->addrlen = addrlen;
+ ap->cstate = cstate;
+
+ switch (ap->addr->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port);
+ break;
+ default:
+ GNUNET_break (0);
+ GNUNET_free (ap);
+ return; /* not supported by us */
+ }
+ ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
+ SOCK_STREAM,
+ 0);
+ if (NULL == ap->sock)
+ {
+ GNUNET_free (ap);
+ return; /* not supported by OS */
+ }
+ if ( (GNUNET_OK !=
+ GNUNET_NETWORK_socket_connect (ap->sock,
+ ap->addr,
+ ap->addrlen)) &&
+ (EINPROGRESS != errno) )
+ {
+ /* maybe refused / unsupported address, try next */
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO,
+ "connect");
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_NETWORK_socket_close (ap->sock));
+ GNUNET_free (ap);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_insert (cstate->ap_head,
+ cstate->ap_tail,
+ ap);
+ ap->task = GNUNET_SCHEDULER_add_write_net (GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
+ ap->sock,
+ &connect_probe_continuation,
+ ap);