<p>Let's learn today how to get the details of a DNS <a href="https://en.wikipedia.org/wiki/CNAME_record">CNAME</a> record using Go. Go provides us with the <a href="https://golang.org/pkg/net/"><code>net</code></a> package to do exactly this. The function we need is called <a href="https://golang.org/pkg/net/#LookupCNAME"><code>LookupCNAME</code></a>.</p> <div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nx">main</span> <span class="kn">import</span> <span class="p">(</span> <span class="s">&quot;errors&quot;</span> <span class="s">&quot;log&quot;</span> <span class="s">&quot;net&quot;</span> <span class="s">&quot;strings&quot;</span> <span class="p">)</span> <span class="kd">func</span> <span class="nx">lookupCNAME</span><span class="p">(</span><span class="nx">host</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="kt">string</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="nx">host</span> <span class="o">==</span> <span class="s">&quot;&quot;</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="nx">errors</span><span class="p">.</span><span class="nx">New</span><span class="p">(</span><span class="s">&quot;Empty host name&quot;</span><span class="p">)</span> <span class="p">}</span> <span class="nx">cname</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">LookupCNAME</span><span class="p">(</span><span class="nx">host</span><span class="p">)</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="nx">errors</span><span class="p">.</span><span class="nx">New</span><span class="p">(</span><span class="s">&quot;Domain name doesn&#39;t exist&quot;</span><span class="p">)</span> <span class="p">}</span> <span class="nx">cname</span> <span class="p">=</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">TrimSuffix</span><span class="p">(</span><span class="nx">cname</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">)</span> <span class="nx">host</span> <span class="p">=</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">TrimSuffix</span><span class="p">(</span><span class="nx">host</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nx">cname</span> <span class="o">==</span> <span class="s">&quot;&quot;</span> <span class="o">||</span> <span class="nx">cname</span> <span class="o">==</span> <span class="nx">host</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="nx">errors</span><span class="p">.</span><span class="nx">New</span><span class="p">(</span><span class="s">&quot;Domain name is not a CNAME&quot;</span><span class="p">)</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">cname</span><span class="p">,</span> <span class="kc">nil</span> <span class="p">}</span> <span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span> <span class="nx">result</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">lookupCNAME</span><span class="p">(</span><span class="s">&quot;api.yellowduck.be&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> <span class="nx">log</span><span class="p">.</span><span class="nx">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">}</span> <span class="nx">log</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">result</span><span class="p">)</span> <span class="p">}</span> </pre></div> <p>The <code>LookupCNAME</code> function is described as follows:</p> <div class="highlight"><pre><span></span><span class="kd">func</span> <span class="nx">LookupCNAME</span><span class="p">(</span><span class="nx">host</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="nx">cname</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> </pre></div> <blockquote><p><code>LookupCNAME</code> returns the canonical name for the given <code>host</code>. Callers that do not care about the canonical name can call <a href="https://golang.org/pkg/net/#LookupHost"><code>LookupHost</code></a> or <a href="https://golang.org/pkg/net/#LookupIP"><code>LookupIP</code></a> directly; both take care of resolving the canonical name as part of the lookup.</p> <p>A canonical name is the final name after following zero or more <code>CNAME</code> records. <code>LookupCNAME</code> does not return an error if host does not contain DNS "CNAME" records, as long as host resolves to address records.</p> </blockquote>

Related Posts

  • Embedding file with Go 1.16
  • Truncating a Unix timestamp to the hour using Go
  • Parsing a key pair from a PEM file in Go
  • Gotcha with defer in Go
  • Pretty-print JSON with Go