I’m sure that it’s due to a silly mistake, but I have been debuging during hours and I couldn’t solve the issue.
In my program, I have a function that returns the address of a given domain. It calls to getaddrinfo, copies the address to a new dinamically asigned variable, sets its pointer into a hostent struct and returns it. Nevertheless, the address returned wasn’t correct. After some debuging I realized that its value changes unexpectedly in some point of the code.
I made a sample program with the relevant part in this issue:
#include <iostream>
#include <string.h>
#include <string>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>
using namespace std;
typedef unsigned long int longip_t;
int main(int argc, char** argv) {
struct addrinfo hints, *res;
struct hostent *final = new hostent;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("automation.whatismyip.com", "80", &hints, &res);
cout << inet_ntoa(((sockaddr_in*)res->ai_addr)->sin_addr) << endl;
in_addr *addr = new in_addr;
memcpy((void*)addr, (void*)(&((sockaddr_in*)res->ai_addr)->sin_addr), sizeof(in_addr));
cout << inet_ntoa(*addr) << endl;
final->h_addr_list = (char**)addr;
cout << inet_ntoa(*addr) << endl;
final->h_addr = (char*)addr; // At this point the value of addr changes
cout << inet_ntoa(*addr) << endl;
cout << inet_ntoa(*(in_addr*)final->h_addr_list) << endl;
exit(0);
}
The output I get:
72.233.89.195
72.233.89.195
72.233.89.195
48.116.218.9
48.116.218.9
The first three IPs are correct, but I get different values for the last two IPs every time I run the program. It looks that the value of addr changes after setting its pointer into the hostent struct.
From
hostentStructure on MSDNSo the above line is really this
From
final->h_addr_list = (char**)addr;, that line becomes thisNow, I believe you see the problem. 🙂
[Update]
The right way to set it is actually easy and automatic. You should call
gethostbyaddrorgethostbyname, and they will return a pointer tohostent. This is well explained in MSDN. If you want to sethostentmanually, which I don’t recommend, you have to create an array of pointers toaddr.s_addrand seth_addr_listto the array. The array should include the lastnullelement. I don’t see any reasons why you want to do it manually as OS does it for you.