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; }
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 {
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; }