Esempio n. 1
0
int gitno_connect(git_transport *t, const char *host, const char *port)
{
	struct addrinfo *info = NULL, *p;
	struct addrinfo hints;
	int ret;
	GIT_SOCKET s = INVALID_SOCKET;

	memset(&hints, 0x0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = AF_UNSPEC;

	if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) {
		giterr_set(GITERR_NET,
			"Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
		return -1;
	}

	for (p = info; p != NULL; p = p->ai_next) {
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

		if (s == INVALID_SOCKET) {
			net_set_error("error creating socket");
			break;
		}

		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
			break;

		/* If we can't connect, try the next one */
		gitno_close(s);
		s = INVALID_SOCKET;
	}

	/* Oops, we couldn't connect to any address */
	if (s == INVALID_SOCKET && p == NULL) {
		giterr_set(GITERR_OS, "Failed to connect to %s", host);
		return -1;
	}

	t->socket = s;
	p_freeaddrinfo(info);

	if (t->use_ssl && ssl_setup(t, host) < 0)
		return -1;

	return 0;
}
Esempio n. 2
0
SockAddr *sk_namelookup(const char *host, char **canonicalname,
                        int address_family)
{
    SockAddr *ret = snew(SockAddr);
    unsigned long a;
    char realhost[8192];
    int hint_family;

    /* Default to IPv4. */
    hint_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
#ifndef NO_IPV6
		   address_family == ADDRTYPE_IPV6 ? AF_INET6 :
#endif
		   AF_UNSPEC);

    /* Clear the structure and default to IPv4. */
    memset(ret, 0, sizeof(SockAddr));
#ifndef NO_IPV6
    ret->ais = NULL;
#endif
    ret->namedpipe = false;
    ret->addresses = NULL;
    ret->resolved = false;
    ret->refcount = 1;
    *realhost = '\0';

    if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
	struct hostent *h = NULL;
	int err = 0;
#ifndef NO_IPV6
	/*
	 * Use getaddrinfo when it's available
	 */
	if (p_getaddrinfo) {
	    struct addrinfo hints;
	    memset(&hints, 0, sizeof(hints));
	    hints.ai_family = hint_family;
	    hints.ai_flags = AI_CANONNAME;
            {
                /* strip [] on IPv6 address literals */
                char *trimmed_host = host_strduptrim(host);
                err = p_getaddrinfo(trimmed_host, NULL, &hints, &ret->ais);
                sfree(trimmed_host);
            }
	    if (err == 0)
		ret->resolved = true;
	} else
#endif
	{
	    /*
	     * Otherwise use the IPv4-only gethostbyname...
	     * (NOTE: we don't use gethostbyname as a fallback!)
	     */
	    if ( (h = p_gethostbyname(host)) )
		ret->resolved = true;
	    else
		err = p_WSAGetLastError();
	}

	if (!ret->resolved) {
	    ret->error = (err == WSAENETDOWN ? "Network is down" :
			  err == WSAHOST_NOT_FOUND ? "Host does not exist" :
			  err == WSATRY_AGAIN ? "Host not found" :
#ifndef NO_IPV6
			  p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
#endif
			  "gethostbyname: unknown error");
	} else {
	    ret->error = NULL;

#ifndef NO_IPV6
	    /* If we got an address info use that... */
	    if (ret->ais) {
		/* Are we in IPv4 fallback mode? */
		/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */
		if (ret->ais->ai_family == AF_INET)
		    memcpy(&a,
			   (char *) &((SOCKADDR_IN *) ret->ais->
				      ai_addr)->sin_addr, sizeof(a));

		if (ret->ais->ai_canonname)
		    strncpy(realhost, ret->ais->ai_canonname, lenof(realhost));
		else
		    strncpy(realhost, host, lenof(realhost));
	    }
	    /* We used the IPv4-only gethostbyname()... */
	    else
#endif
	    {
		int n;
		for (n = 0; h->h_addr_list[n]; n++);
		ret->addresses = snewn(n, unsigned long);
		ret->naddresses = n;
		for (n = 0; n < ret->naddresses; n++) {
		    memcpy(&a, h->h_addr_list[n], sizeof(a));
		    ret->addresses[n] = p_ntohl(a);
		}
		memcpy(&a, h->h_addr, sizeof(a));
		/* This way we are always sure the h->h_name is valid :) */
		strncpy(realhost, h->h_name, sizeof(realhost));
	    }
	}
    } else {
Esempio n. 3
0
File: netops.c Progetto: aep/libgit2
int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int flags)
{
	struct addrinfo *info = NULL, *p;
	struct addrinfo hints;
	GIT_SOCKET s = INVALID_SOCKET;
	int ret;

#ifdef GIT_WIN32
	/* on win32, the WSA context needs to be initialized
	 * before any socket calls can be performed */
	WSADATA wsd;

	if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
		giterr_set(GITERR_OS, "Winsock init failed");
		return -1;
	}

	if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
		WSACleanup();
		giterr_set(GITERR_OS, "Winsock init failed");
		return -1;
	}
#endif

	/* Zero the socket structure provided */
	memset(s_out, 0x0, sizeof(gitno_socket));

	memset(&hints, 0x0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_family = AF_UNSPEC;

	if ((ret = p_getaddrinfo(host, port, &hints, &info)) < 0) {
		giterr_set(GITERR_NET,
			"Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
		return -1;
	}

	for (p = info; p != NULL; p = p->ai_next) {
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

		if (s == INVALID_SOCKET) {
			net_set_error("error creating socket");
			break;
		}

		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
			break;

		/* If we can't connect, try the next one */
		gitno__close(s);
		s = INVALID_SOCKET;
	}

	/* Oops, we couldn't connect to any address */
	if (s == INVALID_SOCKET && p == NULL) {
		giterr_set(GITERR_OS, "Failed to connect to %s", host);
		p_freeaddrinfo(info);
		return -1;
	}

	s_out->socket = s;
	p_freeaddrinfo(info);

#ifdef GIT_SSL
	if ((flags & GITNO_CONNECT_SSL) && ssl_setup(s_out, host, flags) < 0)
		return -1;
#else
	/* SSL is not supported */
	if (flags & GITNO_CONNECT_SSL) {
		giterr_set(GITERR_OS, "SSL is not supported by this copy of libgit2.");
		return -1;
	}
#endif

	return 0;
}