/** * Try to connect to a service configured to use a SOCKS5 proxy. * * @param service_name name of service to connect to * @param cfg configuration to use * @return Connection handle that becomes usable when the handshake completes. * NULL if SOCKS not configured or not configured properly */ struct GNUNET_CONNECTION_Handle * GNUNET_SOCKS_do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_SOCKS_Handshake *ih; struct GNUNET_CONNECTION_Handle *socks5; /* *proxied */ char *host0,*host1,*user,*pass; unsigned long long port0,port1; if (GNUNET_YES != GNUNET_SOCKS_check_service (service_name, cfg)) return NULL; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "SOCKSPORT", &port0)) port0 = 9050; /* A typical Tor client should usually try port 9150 for the TBB too, but * GNUnet can probably assume a system Tor installation. */ if (port0 > 65535 || port0 <= 0) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"), port0, service_name); return NULL; } if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port1)) || (port1 > 65535) || (port1 <= 0) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &host1))) { LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Attempting to proxy service `%s' to invalid port %d or hostname `%s'.\n"), service_name,port1,host1); return NULL; } /* Appeared to still work after host0 corrupted, so either test case is broken, or this whole routine is not being called. */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSHOST", &host0)) host0 = NULL; socks5 = GNUNET_CONNECTION_create_from_connect (cfg, (host0 != NULL)? host0:"127.0.0.1", port0); GNUNET_free_non_null (host0); /* Sets to NULL if they do not exist */ (void) GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSUSER", &user); (void) GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSPASS", &pass); ih = GNUNET_SOCKS_init_handshake(user,pass); if (NULL != user) GNUNET_free (user); if (NULL != pass) GNUNET_free (pass); GNUNET_SOCKS_set_handshake_destination (ih,host1,port1); GNUNET_free (host1); return GNUNET_SOCKS_run_handshake(ih,socks5); }
/** * Try to connect to the service. * * @param service_name name of service to connect to * @param cfg configuration to use * @param attempt counter used to alternate between IP and UNIX domain sockets * @return NULL on error */ static struct GNUNET_CONNECTION_Handle * do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) { struct GNUNET_CONNECTION_Handle *connection; char *hostname; unsigned long long port; /* Never use a local source if a proxy is configured */ if (GNUNET_YES == GNUNET_SOCKS_check_service (service_name,cfg)) return GNUNET_SOCKS_do_connect (service_name,cfg); connection = NULL; if (0 == (attempt % 2)) { /* on even rounds, try UNIX first */ connection = try_unixpath (service_name, cfg); if (NULL != connection) return connection; } if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) { if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &hostname))) { LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Could not determine valid hostname and port for service `%s' from configuration.\n"), service_name); return NULL; } if (0 == strlen (hostname)) { GNUNET_free (hostname); LOG (GNUNET_ERROR_TYPE_WARNING, _("Need a non-empty hostname for service `%s'.\n"), service_name); return NULL; } } else { /* unspecified means 0 (disabled) */ port = 0; hostname = NULL; } if (0 == port) { /* if port is 0, try UNIX */ connection = try_unixpath (service_name, cfg); if (NULL != connection) { GNUNET_free_non_null (hostname); return connection; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", service_name); GNUNET_free_non_null (hostname); return NULL; } connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); GNUNET_free (hostname); return connection; }