4

I've programmed networked applications, but primarily in Python.

I'm writing a C++ application and I'm a little fuzzy on exactly what the syntax should be to look up a domain name and connect to it's IP address.

Specifically, I'm not sure how to go form the result of a gethostbyname() call to a socket.

My code currently looks like this:

const hostent* host = GetHost(); //This works correctly
    if (!host) {
        DebugMessage("Bad host", "Could not resolve host");
        return NULL;
    }
    DebugMessage("Got host", host->h_name);

    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    //This funky cast is what i'm concerned about
    addr.sin_addr.s_addr = (*((in_addr*)(host->h_addr_list[0]))).s_addr;
    addr.sin_port = htons(80);

    DebugMessage("addr", (*((in_addr*)(host->h_addr_list[0]))).s_addr);

    int c = connect(s, (SOCKADDR*)&addr, sizeof(addr));
    int le = WSAGetLastError();
    if (c == SOCKET_ERROR) {
        //etc...

It does work, but It seems to me that that funky cast for assigning the s_addr seems too complex for what I'm actually doing, leading me to beleive that this is not the way it "should be done". Am I just too used to high level languages, and this is the way it's supposed to be, or am I missing a utility function somewhere?

Thanks for the help.

EB.
  • 3,383
  • 5
  • 31
  • 43

2 Answers2

1

Technically you should use h_addrtype rather than assume AF_INET and then interpret h_addr_list based on that type. Once you are already assuming AF_INET (both in the socket and in connect) you may as well assume that h_addr_list[0] is an in_addr as you are doing. You could check h_addrtype in case you got an AAAA record (IPv6) so you can reject it rather than mis-cast it.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
  • So if I assume `h_addrtype` is definately `AF_INET`, the code I posted is basically correct? That is, this is how I should continue doing it? Thanks for the help. – EB. Aug 31 '11 at 20:22
1

I believe the latest and recommended way to resolve domain name is to use getaddrinfo (windows, linux).

As far as I know, there is no standard way of making a lookup asynchronously, therefore it's quite common to spawn a thread dedicated to doing DNS lookups.

Arvid
  • 10,915
  • 1
  • 32
  • 40
  • My usual favourite is to use `libasyncns`, which creates a sidecar thread or process, communicating via a pipe or socketpair to the main loop. It's easy to add this filehandle to a select/poll/etc.. loop and handle it in a nonblocking way. http://0pointer.de/lennart/projects/libasyncns/ – LeoNerd Jul 04 '12 at 10:07