Ваш lookup_host()
не возвращает адресные данные обратно вызывающей стороне правильно, даже близко не. addrinfo
содержит указатели на данные вне addrinfo
. Но вы просто копируете сам addrinfo
в вызывающую сторону, но ни на одну из данных, на которые он указывает.
Попробуйте вместо этого что-нибудь еще:
int lookup_host(const wchar_t *host, int family, void *sa)
{
struct addrinfoW hints;
struct addrinfoW *res, *addr;
int errcode, addrlen, returnval;
void *ptr;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
errcode = GetAddrInfoW(host, L"80", &hints, &res);
//GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, &res, NULL, NULL, NULL, NULL);
if (errcode != 0)
{
//perror("getaddrinfo");
return -1;
}
returnval = 0;
for(addr = res; addr != NULL; addr = addr->ai_next)
{
switch (addr->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *) addr->ai_addr)->sin_addr;
addrlen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
addrlen = sizeof(struct sockaddr_in6);
break;
default:
continue;
}
CopyMemory(sa, ptr, addrlen);
returnval = 1;
break;
}
FreeAddrInfoW(res);
return returnval;
}
...
struct sockaddr_in sa;
if (lookup_host(host, AF_INET, &sa) != 1) {
return -1;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
return -1;
}
if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
#ifdef _DEBUG
printf("Error: %d\n", GetLastError());
#endif // _DEBUG
closesocket(sock);
return -2;
}
...
Обратите внимание, что приведенное выше возвращает только первый найденный адрес. Имя хоста может преобразовываться в несколько IP-адресов, и на вашем компьютере может не быть маршрута ко всем из них. Таким образом, вы должны пытаться подключиться к каждому указанному адресу, пока он не будет успешным, например:
int lookup_host(const wchar_t *host, int family, struct addrinfoW **addrs)
{
struct addrinfoW hints;
int errcode;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
errcode = GetAddrInfoW(host, L"80", &hints, addrs);
//GetAddrInfoExW(host, L"80", NS_ALL, NULL, &hints, addrs, NULL, NULL, NULL, NULL);
if (errcode != 0)
{
//perror("getaddrinfo");
return -1;
}
return 0;
}
...
struct addrInfoW *res, *addr;
if (lookup_host(host, AF_INET, &res) < 0) { // or AF_INET6, or AF_UNSPEC
return -1;
}
sock = INVALID_SOCKET;
for(addr = res; addr != NULL; addr = addr->ai_next)
{
sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sock == INVALID_SOCKET) {
break;
}
if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) {
break;
}
#ifdef _DEBUG
printf("Error: %d\n", GetLastError());
#endif // _DEBUG
closesocket(sock);
sock = INVALID_SOCKET;
}
FreeAddrInfoW(res);
if (sock == INVALID_SOCKET) {
return -2;
}
...