Example #1
0
static SOCKET
xmlNanoHTTPConnectHost(const char *host, int port)
{
    struct hostent *h;
    struct sockaddr *addr = NULL;
    struct in_addr ia;
    struct sockaddr_in sockin;

#ifdef SUPPORT_IP6
    struct in6_addr ia6;
    struct sockaddr_in6 sockin6;
#endif
    int i;
    SOCKET s;

    memset (&sockin, 0, sizeof(sockin));
#ifdef SUPPORT_IP6
    memset (&sockin6, 0, sizeof(sockin6));
#endif

#if !defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && defined(RES_USE_INET6)
    if (have_ipv6 ())
    {
	if (!(_res.options & RES_INIT))
	    res_init();
	_res.options |= RES_USE_INET6;
    }
#endif

#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
    if (have_ipv6 ())
#endif
#if defined(HAVE_GETADDRINFO) && (defined(SUPPORT_IP6) || defined(_WIN32))
    {
	int status;
	struct addrinfo hints, *res, *result;

	result = NULL;
	memset (&hints, 0,sizeof(hints));
	hints.ai_socktype = SOCK_STREAM;

	status = getaddrinfo (host, NULL, &hints, &result);
	if (status) {
	    __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");
	    return INVALID_SOCKET;
	}

	for (res = result; res; res = res->ai_next) {
	    if (res->ai_family == AF_INET) {
		if (res->ai_addrlen > sizeof(sockin)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    freeaddrinfo (result);
		    return INVALID_SOCKET;
		}
		memcpy (&sockin, res->ai_addr, res->ai_addrlen);
		sockin.sin_port = htons (port);
		addr = (struct sockaddr *)&sockin;
#ifdef SUPPORT_IP6
	    } else if (have_ipv6 () && (res->ai_family == AF_INET6)) {
		if (res->ai_addrlen > sizeof(sockin6)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    freeaddrinfo (result);
		    return INVALID_SOCKET;
		}
		memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
		sockin6.sin6_port = htons (port);
		addr = (struct sockaddr *)&sockin6;
#endif
	    } else
		continue;              /* for */

	    s = xmlNanoHTTPConnectAttempt (addr);
	    if (s != INVALID_SOCKET) {
		freeaddrinfo (result);
		return (s);
	    }
	}

	if (result)
	    freeaddrinfo (result);
    }
#endif
#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
    else
#endif
#if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
    {
	h = gethostbyname (host);
	if (h == NULL) {

/*
 * Okay, I got fed up by the non-portability of this error message
 * extraction code. it work on Linux, if it work on your platform
 * and one want to enable it, send me the defined(foobar) needed
 */
#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)
	    const char *h_err_txt = "";

	    switch (h_errno) {
		case HOST_NOT_FOUND:
		    h_err_txt = "Authoritive host not found";
		    break;

		case TRY_AGAIN:
		    h_err_txt =
			"Non-authoritive host not found or server failure.";
		    break;

		case NO_RECOVERY:
		    h_err_txt =
			"Non-recoverable errors:  FORMERR, REFUSED, or NOTIMP.";
		    break;

		case NO_ADDRESS:
		    h_err_txt =
			"Valid name, no data record of requested type.";
		    break;

		default:
		    h_err_txt = "No error text defined.";
		    break;
	    }
	    __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt);
#else
	    __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");
#endif
	    return INVALID_SOCKET;
	}

	for (i = 0; h->h_addr_list[i]; i++) {
	    if (h->h_addrtype == AF_INET) {
		/* A records (IPv4) */
		if ((unsigned int) h->h_length > sizeof(ia)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    return INVALID_SOCKET;
		}
		memcpy (&ia, h->h_addr_list[i], h->h_length);
		sockin.sin_family = h->h_addrtype;
		sockin.sin_addr = ia;
		sockin.sin_port = (u_short)htons ((unsigned short)port);
		addr = (struct sockaddr *) &sockin;
#ifdef SUPPORT_IP6
	    } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) {
		/* AAAA records (IPv6) */
		if ((unsigned int) h->h_length > sizeof(ia6)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    return INVALID_SOCKET;
		}
		memcpy (&ia6, h->h_addr_list[i], h->h_length);
		sockin6.sin6_family = h->h_addrtype;
		sockin6.sin6_addr = ia6;
		sockin6.sin6_port = htons (port);
		addr = (struct sockaddr *) &sockin6;
#endif
	    } else
		break;              /* for */

	    s = xmlNanoHTTPConnectAttempt (addr);
	    if (s != INVALID_SOCKET)
		return (s);
	}
    }
#endif

#ifdef DEBUG_HTTP
    xmlGenericError(xmlGenericErrorContext,
                    "xmlNanoHTTPConnectHost:  unable to connect to '%s'.\n",
                    host);
#endif
    return INVALID_SOCKET;
}
Example #2
0
/* Connect to a CDDB server */
static int 
CDDBConnect (CDDBServer *server)
{
	int sock = -1;
#ifdef ENABLE_IPV6
	struct sockaddr_in6 sin6;
	struct addrinfo hints, *result, *res;  /*info abt the IP of node*/
#endif
	struct sockaddr_in sin;
	struct hostent *host;
	char *sname;
  
#ifdef ENABLE_IPV6
	if (have_ipv6 ()) {
		result = NULL;

		memset (&sin6, 0 , sizeof (sin6));	
		sin6.sin6_family = AF_INET6;

		if (server->use_proxy) {
			sin6.sin6_port = htons (server->proxy->port);
		} else {
			sin6.sin6_port = htons (server->port);
		}
	}
#endif

	memset (&sin, 0, sizeof (sin));
	sin.sin_family = AF_INET;

	if (server->use_proxy)
		sin.sin_port=htons(server->proxy->port);
	else
		sin.sin_port = htons(server->port);
  
	if (server->use_proxy)
		sname=server->proxy->name;
	else
		sname=server->name;
  
#ifdef ENABLE_IPV6
	if (have_ipv6 ()) {
		memset (&hints, 0, sizeof (hints));
		hints.ai_socktype = SOCK_STREAM;

		if ((getaddrinfo (sname, NULL, &hints, &result)) != 0) {
			return -1;
		}
      
		for (res = result; res; res = res->ai_next) {

			if (res->ai_family != AF_INET && res->ai_family != AF_INET6) {
				continue;
			}

			sock = socket (res->ai_family, SOCK_STREAM, 0);
			if (sock < 0) {
				continue;
			}

			if (res->ai_family == AF_INET) {
				memcpy (&sin.sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof (struct in_addr));

				if (connect (sock, (struct sockaddr *)&sin, sizeof (sin)) != -1) {
					break;
				}
			}

			if (res->ai_family == AF_INET6) {
				memcpy (&sin6.sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, sizeof (struct in6_addr));
        
				if (connect (sock, (struct sockaddr *)&sin6, sizeof (sin6)) != -1) {
					break;
				}
			}

			close (sock);
		}

		freeaddrinfo (result);

		if (!res) {
			/* No valid address found. */
			return -1;
		}
	} else
#endif  /*IPv4*/
	{
		sin.sin_addr.s_addr = inet_addr (sname);
#ifdef SOLARIS
		if (sin.sin_addr.s_addr == (unsigned long)-1)
#else
		if (sin.sin_addr.s_addr == INADDR_NONE)
#endif
		{
			host = gethostbyname (sname);
			if (host == NULL) {
				return -1;
			}

			bcopy (host->h_addr, &sin.sin_addr, host->h_length);
		}

		sock = socket (AF_INET, SOCK_STREAM, 0);
		if (sock < 0) {
			return -1;
		}
  
		if (connect (sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
			return -1;
		}

	}

	return sock;
}
Example #3
0
static void parse_ignore_host(gpointer data, gpointer user_data)
{
    gchar *hostname, *input, *netmask;
    gboolean ip_addr = FALSE, has_error = FALSE;
    struct in_addr host;
#ifdef ENABLE_IPV6
    struct in6_addr host6, mask6;
    gint i;
#endif
    ProxyHostAddr *elt;

    input = (gchar *) data;
    elt = g_new0(ProxyHostAddr, 1);
    if ((netmask = strchr(input, '/')) != NULL) {
	hostname = g_strndup(input, netmask - input);
	++netmask;
    } else {
	hostname = g_ascii_strdown(input, -1);
    }
    if (inet_pton(AF_INET, hostname, &host) > 0) {
	ip_addr = TRUE;
	elt->type = PROXY_IPv4;
	elt->addr.s_addr = host.s_addr;
	if (netmask) {
	    gchar *endptr;
	    gint width = strtol(netmask, &endptr, 10);

	    if (*endptr != '\0' || width < 0 || width > 32) {
		has_error = TRUE;
	    }
	    elt->mask.s_addr = htonl(~0 << width);
	    elt->addr.s_addr &= elt->mask.s_addr;
	} else {
	    elt->mask.s_addr = 0xffffffff;
	}
    }
#ifdef ENABLE_IPV6
    else if (have_ipv6() && inet_pton(AF_INET6, hostname, &host6) > 0) {
	ip_addr = TRUE;
	elt->type = PROXY_IPv6;
	for (i = 0; i < 16; ++i) {
	    elt->addr6.s6_addr[i] = host6.s6_addr[i];
	}
	if (netmask) {
	    gchar *endptr;
	    gint width = strtol(netmask, &endptr, 10);

	    if (*endptr != '\0' || width < 0 || width > 128) {
		has_error = TRUE;
	    }
	    for (i = 0; i < 16; ++i) {
		elt->mask6.s6_addr[i] = 0;
	    }
	    for (i = 0; i < width / 8; i++) {
		elt->mask6.s6_addr[i] = 0xff;
	    }
	    elt->mask6.s6_addr[i] = (0xff << (8 - width % 8)) & 0xff;
	    ipv6_network_addr(&elt->addr6, &mask6, &elt->addr6);
	} else {
	    for (i = 0; i < 16; ++i) {
		elt->mask6.s6_addr[i] = 0xff;
	    }
	}
    }
#endif

    if (ip_addr) {
	if (!has_error) {
	    gchar *dst = g_new0(gchar, INET_ADDRSTRLEN);

	    gl_ignore_addrs = g_slist_append(gl_ignore_addrs, elt);
	    DEBUG_HTTP(("Host %s/%s does not go through proxy.",
			hostname, inet_ntop(AF_INET, &elt->mask,
					    dst, INET_ADDRSTRLEN)));
	    g_free(dst);
	}
	g_free(hostname);
    } else {
	/* It is a hostname. */
	gl_ignore_hosts = g_slist_append(gl_ignore_hosts, hostname);
	DEBUG_HTTP(("Host %s does not go through proxy.", hostname));
	g_free(elt);
    }
}
Example #4
0
int bg_listen_socket_create_inet(bg_socket_address_t * addr,
                                 int port,
                                 int queue_size,
                                 int flags)
  {
  int ret, err, use_ipv6 = 0;
  struct sockaddr_in  name_ipv4;
  struct sockaddr_in6 name_ipv6;

  if(addr)
    {
    if(addr->addr.ss_family == AF_INET6)
      use_ipv6 = 1;
    }
  else if(flags & BG_SOCKET_LOOPBACK)
    use_ipv6 = have_ipv6();
  
  memset(&name_ipv4, 0, sizeof(name_ipv4));
  memset(&name_ipv6, 0, sizeof(name_ipv6));
  
  if(use_ipv6)
    ret = create_socket(PF_INET6, SOCK_STREAM, 0);
  else
    ret = create_socket(PF_INET, SOCK_STREAM, 0);
  
  /* Create the socket. */
  if(ret < 0)
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot create TCP server socket");
    return -1;
    }
  
  /* Give the socket a name. */

  if(addr)
    {
    err = bind(ret, (struct sockaddr*)&addr->addr, addr->len);
    }
  else if(use_ipv6)
    {
    name_ipv6.sin6_family = AF_INET6;
    name_ipv6.sin6_port   = htons(port);
    if(flags & BG_SOCKET_LOOPBACK)
      name_ipv6.sin6_addr = in6addr_loopback;
    else
      name_ipv6.sin6_addr = in6addr_any;

    err = bind(ret, (struct sockaddr *)&name_ipv6, sizeof(name_ipv6));
    }
  else
    {
    name_ipv4.sin_family = AF_INET;
    name_ipv4.sin_port = htons(port);
    if(flags & BG_SOCKET_LOOPBACK)
      name_ipv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    else
      name_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
    err = bind(ret, (struct sockaddr *)&name_ipv4, sizeof(name_ipv4));
    }
  
  if(err < 0)
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot bind inet socket: %s", strerror(errno));
    return -1;
    }
  if(listen(ret, queue_size))
    {
    bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot put socket into listening mode");
    return -1;
    }
  return ret;
  }
Example #5
0
static gboolean proxy_should_for_hostname(const char *hostname)
{
#ifdef ENABLE_IPV6
    struct in6_addr in6, net6;
#endif
    struct in_addr in;
    GSList *elt;
    ProxyHostAddr *addr;


    /* IPv4 address */
    if (inet_pton(AF_INET, hostname, &in) > 0) {
	for (elt = gl_ignore_addrs; elt; elt = g_slist_next(elt)) {
	    addr = (ProxyHostAddr *) (elt->data);
	    if (addr->type == PROXY_IPv4
		&& (in.s_addr & addr->mask.s_addr) == addr->addr.s_addr) {
		DEBUG_HTTP(("Host %s using direct connection.", hostname));
		return FALSE;
	    }
	}
    }
#ifdef ENABLE_IPV6
    else if (have_ipv6() && inet_pton(AF_INET6, hostname, &in6)) {
	for (elt = gl_ignore_addrs; elt; elt = g_slist_next(elt)) {
	    addr = (ProxyHostAddr *) (elt->data);
	    ipv6_network_addr(&in6, &addr->mask6, &net6);
	    if (addr->type == PROXY_IPv6
		&& IN6_ARE_ADDR_EQUAL(&net6, &addr->addr6)) {
		DEBUG_HTTP(("Host %s using direct connection.", hostname));
		return FALSE;
	    }
	    /* Handle IPv6-wrapped IPv4 addresses. */
	    else if (addr->type == PROXY_IPv4
		     && IN6_IS_ADDR_V4MAPPED(&net6)) {
		guint32 v4addr;

		v4addr = net6.s6_addr[12] << 24 | net6.
		    s6_addr[13] << 16 | net6.
		    s6_addr[14] << 8 | net6.s6_addr[15];
		if ((v4addr & addr->mask.s_addr) != addr->addr.s_addr) {
		    DEBUG_HTTP(("Host %s using direct connection.",
				hostname));
		    return FALSE;
		}
	    }
	}
    }
#endif
    /* All hostnames (foo.bar.com) -- independent of IPv4 or IPv6 */

    /* If there are IPv6 addresses in the ignore_hosts list but we do not
     * have IPv6 available at runtime, then those addresses will also fall
     * through to here (and harmlessly fail to match). */
    else {
	gchar *hn = g_ascii_strdown(hostname, -1);

	for (elt = gl_ignore_hosts; elt; elt = g_slist_next(elt)) {
	    if (*(gchar *) (elt->data) == '*') {
		if (g_str_has_suffix(hn, (gchar *) (elt->data) + 1)) {
		    DEBUG_HTTP(("Host %s using direct connection.", hn));
		    g_free(hn);
		    return FALSE;
		}
	    } else if (strcmp(hn, elt->data) == 0) {
		DEBUG_HTTP(("Host %s using direct connection.", hn));
		g_free(hn);
		return FALSE;
	    }
	}
	g_free(hn);
    }

    return TRUE;
}