title: getting local host name as destination using getaddrinfo/getnameinfo
body: <p>I am looking through some out-of-date code which uses <code>getaddrinfo</code> and <code>getnameinfo</code> to determine host name information and then falls back to <code>gethostname</code> and <code>gethostbyname</code> if <code>getnameinfo</code> fails.</p>
  
  <p>Now, this seems wrong to me.  I am trying to understand the intent of the code so that I can make a recommendation.  I don't want to repost the entire code here because it is long and complicated, but I'll try to summarize:</p>
  
  <p>As far as I can tell, the point of this code is to generate a string which can be used by another process to connect to a listening socket.  This seems to be not just for local processes, but also for remote hosts to connect back to this computer.</p>
  
  <p>So the code in question is basically doing the following:</p>
  
  <ul>
  <li><code>getaddrinfo(node = NULL, service = port, hints.ai_flags = AI_PASSIVE, ai);</code> -- this gets a list of possible arguments for <code>socket()</code> that can be used with <code>bind()</code>.</li>
  <li>go through the list of results and create a socket.</li>
  <li>first time a socket is successfully created, this is selected as the "used" <code>addrinfo</code>.</li>
  <li>for the <code>ai_addr</code> of the selected <code>addrinfo</code>, call <code>getnameinfo()</code> to get the associated host name.</li>
  <li>if this fails, call <code>gethostname()</code>, then look up <code>gethostbyname()</code> on the result.</li>
  </ul>
  
  <p>There are a few reasons I think this is wrong, but I want to verify my logic.  Firstly, it seems from some experiments that <code>getnameinfo()</code> pretty much always fails here.  I suppose that the input address is unknown, since it is a listening socket, not a destination, so it doesn't need a valid IP from this point of view.  Then, calling <code>gethostname()</code> and passing the result to <code>gethostbyname()</code> pretty much always returns the same result as <code>gethostname()</code> by itself.  In other words, it's just verifying the local host name, and seems pointless to me.  This is problematic because it's not even necessarily usable by remote hosts, is it?</p>
  
  <p>Somehow I think it's possible that the whole idea of trying to determine your own host name on the subnet is not that useful, but rather you must ping a message to another host and see what IP address they see it as.  (Unfortunately in this context that doesn't make sense, since I don't know other peers at this level of the program.)  For instance, the local host could have more than one NIC and therefore multiple IP addresses, so trying to determine a single host-address pair is nonsensical.  (Is the correct resolution to just <code>bind()</code> and simultaneously listen on <em>all</em> <code>addrinfo</code> results?)</p>
  
  <p>I also noticed that one can get names resolved by just passing them in to <code>getaddrinfo()</code> and setting the <code>AI_CANONNAME</code> flag, meaning the <code>getnameinfo()</code> step may be redundant.  However, I guess this is not done here because they are trying to determine some kind of unbiased view of the hostname without supplying it apriori.  Of course, it fails, and they end up using <code>gethostname()</code> anyways!  I also tried supplying "localhost" to <code>getaddrinfo()</code>, and it reports in ai_canonname` the host name under Linux, but just results in "localhost" on OS X, so not so useful since this is supposed to be cross-platform.</p>
  
  <p>I guess to summarize, my question is, what is the <em>correct</em> way, if one exists, to get a local hostname that can be announced to subnet peers, in modern socket programming?  I am leaning towards replacing this code with simply returning the results of <code>gethostname()</code>, but I'm wondering if there's a more appropriate solution using modern calls like <code>getaddrinfo()</code>.</p>
  
  <p>If the answer is that there's no way to do this, I'll just have to use <code>gethostname()</code> anyways since I must return something here, or it would break the API.</p>