<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Praful's Blog]]></title><description><![CDATA[Praful's Blog]]></description><link>https://blogs.praful.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 21:39:08 GMT</lastBuildDate><atom:link href="https://blogs.praful.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Doing DNS Resolution Manually]]></title><description><![CDATA[# The O.G hosts.txt
The hosts.txt file is a plain text file used to map hostnames to IP addresses, allowing for manual DNS resolution. It is commonly found in the C:\Windows\System32\drivers\etc directory on Windows systems and in /etc on Unix-based ...]]></description><link>https://blogs.praful.dev/doing-dns-resolution-manually</link><guid isPermaLink="true">https://blogs.praful.dev/doing-dns-resolution-manually</guid><category><![CDATA[dns]]></category><dc:creator><![CDATA[Praful M]]></dc:creator><pubDate>Sat, 12 Jul 2025 19:28:29 GMT</pubDate><content:encoded><![CDATA[<p># The O.G <code>hosts.txt</code></p>
<p>The <code>hosts.txt</code> file is a plain text file used to map hostnames to IP addresses, allowing for manual DNS resolution. It is commonly found in the <code>C:\Windows\System32\drivers\etc</code> directory on Windows systems and in <code>/etc</code> on Unix-based systems.</p>
<p>This file can be edited to override DNS settings, redirect traffic, or block access to specific websites by associating them with invalid IP addresses.</p>
<pre><code class="lang-c"><span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>       localhost
<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>       myserver.local
<span class="hljs-number">142.250</span><span class="hljs-number">.183</span><span class="hljs-number">.78</span>  google.com
</code></pre>
<p>If you add <code>myserver.local</code> to the <code>/etc/hosts</code> file, it will direct to the IP address <code>127.0.0.1</code> whenever you access the site in a browser. Before querying a DNS server, the request will first check the <code>/etc/hosts</code> file. If the entry is not found, it will then proceed to query a DNS server, including any caching mechanisms in place.</p>
<p>Using the <code>hosts.txt</code> file can lead to performance issues due to the need for manual updates and potential conflicts with DNS servers. Additionally, it lacks the dynamic capabilities of DNS, making it less efficient for managing large or frequently changing networks.</p>
<h1 id="heading-getting-httpswwwexamplecomhttpswwwexamplecom">Getting <a target="_blank" href="https://www.example.com"><code>https://www.example.com</code></a></h1>
<pre><code class="lang-mermaid">sequenceDiagram
    participant User as User
    participant Browser as Browser
    participant DNS as DNS Resolver
    participant Root as Root DNS Server
    participant TLD as TLD DNS Server
    participant Authoritative as Authoritative DNS Server
    participant Server as Web Server

    User-&gt;&gt;Browser: Enter URL (https://www.example.com)
    Browser-&gt;&gt;DNS: DNS Query for www.example.com
    DNS-&gt;&gt;Root: Query for .com
    Root--&gt;&gt;DNS: Referral to TLD DNS Server
    DNS-&gt;&gt;TLD: Query for www.example.com
    TLD--&gt;&gt;DNS: Referral to Authoritative DNS Server
    DNS-&gt;&gt;Authoritative: Query for www.example.com
    Authoritative--&gt;&gt;DNS: IP Address of www.example.com
    DNS--&gt;&gt;Browser: IP Address of www.example.com
    Browser-&gt;&gt;Server: HTTP Request to IP Address
    Server--&gt;&gt;Browser: HTTP Response
    Browser--&gt;&gt;User: Display Web Page
</code></pre>
<p>This entire process is done manually, so if I simply tell you what happens, you might not grasp it or agree with the concept. Let's go through each step manually to ensure we fully understand what's occurring behind the scenes.</p>
<h2 id="heading-querying-the-root-server-for-a-examplecomhttpexamplecom-tld-server">Querying the Root Server for a <a target="_blank" href="http://example.com">example.com</a> TLD server</h2>
<p>To understand how DNS resolution works, let's walk through the process of resolving <a target="_blank" href="http://example.com"><code>example.com</code></a> using the <code>dig</code> command at each level of the DNS hierarchy. First, we query a <strong>root DNS server</strong> with:</p>
<pre><code class="lang-bash">dig example.com A @a.root-servers.net
</code></pre>
<pre><code class="lang-c">; &lt;&lt;&gt;&gt; DiG <span class="hljs-number">9.18</span><span class="hljs-number">.30</span><span class="hljs-number">-0u</span>buntu0<span class="hljs-number">.24</span><span class="hljs-number">.04</span><span class="hljs-number">.2</span>-Ubuntu &lt;&lt;&gt;&gt; example.com A @a.root-servers.net
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: <span class="hljs-number">55436</span>
;; flags: qr rd; QUERY: <span class="hljs-number">1</span>, ANSWER: <span class="hljs-number">0</span>, AUTHORITY: <span class="hljs-number">13</span>, ADDITIONAL: <span class="hljs-number">27</span>
;; WARNING: recursion requested but <span class="hljs-keyword">not</span> available

;; OPT PSEUDOSECTION:
; EDNS: version: <span class="hljs-number">0</span>, flags:; udp: <span class="hljs-number">4096</span>
;; QUESTION SECTION:
;example.com.            IN    A

;; AUTHORITY SECTION:
com.            <span class="hljs-number">172800</span>    IN    NS    l.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    j.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    h.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    d.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    b.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    f.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    k.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    m.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    i.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    g.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    a.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    c.gtld-servers.net.
com.            <span class="hljs-number">172800</span>    IN    NS    e.gtld-servers.net.

;; ADDITIONAL SECTION:
l.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.41</span><span class="hljs-number">.162</span><span class="hljs-number">.30</span>
l.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">500</span>:d937::<span class="hljs-number">30</span>
j.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.48</span><span class="hljs-number">.79</span><span class="hljs-number">.30</span>
j.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">502</span>:<span class="hljs-number">7094</span>::<span class="hljs-number">30</span>
h.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.54</span><span class="hljs-number">.112</span><span class="hljs-number">.30</span>
h.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">502</span>:<span class="hljs-number">8</span>cc::<span class="hljs-number">30</span>
d.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.31</span><span class="hljs-number">.80</span><span class="hljs-number">.30</span>
d.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">500</span>:<span class="hljs-number">856</span>e::<span class="hljs-number">30</span>
b.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.33</span><span class="hljs-number">.14</span><span class="hljs-number">.30</span>
b.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:<span class="hljs-number">231</span>d::<span class="hljs-number">2</span>:<span class="hljs-number">30</span>
f.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.35</span><span class="hljs-number">.51</span><span class="hljs-number">.30</span>
f.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:d414::<span class="hljs-number">30</span>
k.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.52</span><span class="hljs-number">.178</span><span class="hljs-number">.30</span>
k.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:d2d::<span class="hljs-number">30</span>
m.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.55</span><span class="hljs-number">.83</span><span class="hljs-number">.30</span>
m.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">501</span>:b1f9::<span class="hljs-number">30</span>
i.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.43</span><span class="hljs-number">.172</span><span class="hljs-number">.30</span>
i.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:<span class="hljs-number">39</span>c1::<span class="hljs-number">30</span>
g.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.42</span><span class="hljs-number">.93</span><span class="hljs-number">.30</span>
g.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:eea3::<span class="hljs-number">30</span>
a.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.5</span><span class="hljs-number">.6</span><span class="hljs-number">.30</span>
a.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:a83e::<span class="hljs-number">2</span>:<span class="hljs-number">30</span>
c.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.26</span><span class="hljs-number">.92</span><span class="hljs-number">.30</span>
c.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:<span class="hljs-number">83</span>eb::<span class="hljs-number">30</span>
e.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    A    <span class="hljs-number">192.12</span><span class="hljs-number">.94</span><span class="hljs-number">.30</span>
e.gtld-servers.net.    <span class="hljs-number">172800</span>    IN    AAAA    <span class="hljs-number">2001</span>:<span class="hljs-number">502</span>:<span class="hljs-number">1</span>ca1::<span class="hljs-number">30</span>

;; Query time: <span class="hljs-number">233</span> msec
;; SERVER: <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:ba3e::<span class="hljs-number">2</span>:<span class="hljs-number">30</span>#<span class="hljs-number">53</span>(a.root-servers.net) (UDP)
;; WHEN: Sat Jun <span class="hljs-number">07</span> <span class="hljs-number">17</span>:<span class="hljs-number">03</span>:<span class="hljs-number">55</span> IST <span class="hljs-number">2025</span>
;; MSG SIZE  rcvd: <span class="hljs-number">836</span>
</code></pre>
<p>This doesn't return the IP address of <a target="_blank" href="http://example.com"><code>example.com</code></a> but instead provides a list of <code>.com</code> TLD name servers, such as <a target="_blank" href="http://a.gtld-servers.net"><code>a.gtld-servers.net</code></a>, <a target="_blank" href="http://b.gtld-servers.net"><code>b.gtld-servers.net</code></a>, etc., because the root servers only know where to find Top-Level Domain (TLD) servers.</p>
<p>Also, note the warning indicating that recursion was requested but is not available. This occurs because a root server, such as <a target="_blank" href="http://a.root-servers.net">a.root-servers.net</a>, only provides <code>Authoritative</code> responses. In other words, it will not go out of its way to assist further.</p>
<p>A root server (like <a target="_blank" href="http://a.root-servers.net"><code>a.root-servers.net</code></a>) <strong>only gives authoritative responses</strong>. It doesn’t do the dirty work for you. It just says “go ask someone else.”</p>
<p>But a public recursive resolver (like <code>1.1.1.1</code>) is built to go all the way and bring you the final answer. It will <strong>do the full DNS resolution</strong> on your behalf.</p>
<h2 id="heading-querying-the-tld-server-for-examplecomhttpexamplecom">Querying the TLD Server for <a target="_blank" href="http://example.com">example.com</a></h2>
<pre><code class="lang-c">dig example.com A @a.gtld-servers.net
</code></pre>
<pre><code class="lang-c">razor@beast:~$ dig example.com A @a.gtld-servers.net

; &lt;&lt;&gt;&gt; DiG <span class="hljs-number">9.18</span><span class="hljs-number">.30</span><span class="hljs-number">-0u</span>buntu0<span class="hljs-number">.24</span><span class="hljs-number">.04</span><span class="hljs-number">.2</span>-Ubuntu &lt;&lt;&gt;&gt; example.com A @a.gtld-servers.net
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: <span class="hljs-number">50147</span>
;; flags: qr rd; QUERY: <span class="hljs-number">1</span>, ANSWER: <span class="hljs-number">0</span>, AUTHORITY: <span class="hljs-number">2</span>, ADDITIONAL: <span class="hljs-number">1</span>
;; WARNING: recursion requested but <span class="hljs-keyword">not</span> available

;; OPT PSEUDOSECTION:
; EDNS: version: <span class="hljs-number">0</span>, flags:; udp: <span class="hljs-number">4096</span>
;; QUESTION SECTION:
;example.com.            IN    A

;; AUTHORITY SECTION:
example.com.        <span class="hljs-number">172800</span>    IN    NS    a.iana-servers.net.
example.com.        <span class="hljs-number">172800</span>    IN    NS    b.iana-servers.net.

;; Query time: <span class="hljs-number">221</span> msec
;; SERVER: <span class="hljs-number">2001</span>:<span class="hljs-number">503</span>:a83e::<span class="hljs-number">2</span>:<span class="hljs-number">30</span>#<span class="hljs-number">53</span>(a.gtld-servers.net) (UDP)
;; WHEN: Sat Jun <span class="hljs-number">07</span> <span class="hljs-number">17</span>:<span class="hljs-number">13</span>:<span class="hljs-number">19</span> IST <span class="hljs-number">2025</span>
;; MSG SIZE  rcvd: <span class="hljs-number">88</span>
</code></pre>
<p>This again doesn’t give us the final IP but tells us which <strong>authoritative name servers</strong> are responsible for <a target="_blank" href="http://example.com"><code>example.com</code></a>, specifically <a target="_blank" href="http://a.iana-servers.net"><code>a.iana-servers.net</code></a> and <a target="_blank" href="http://b.iana-servers.net"><code>b.iana-servers.net</code></a>. These servers hold the actual DNS records for the domain. Finally, we query one of these authoritative servers:</p>
<h2 id="heading-querying-the-authoritative-server">Querying the Authoritative Server</h2>
<p><code>dig</code> <a target="_blank" href="http://example.com"><code>example.com</code></a> <code>A @</code><a target="_blank" href="http://a.iana-servers.net"><code>a.iana-servers.net</code></a></p>
<pre><code class="lang-c">; &lt;&lt;&gt;&gt; DiG <span class="hljs-number">9.18</span><span class="hljs-number">.30</span><span class="hljs-number">-0u</span>buntu0<span class="hljs-number">.24</span><span class="hljs-number">.04</span><span class="hljs-number">.2</span>-Ubuntu &lt;&lt;&gt;&gt; example.com A @a.iana-servers.net
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: <span class="hljs-number">49221</span>
;; flags: qr aa rd; QUERY: <span class="hljs-number">1</span>, ANSWER: <span class="hljs-number">6</span>, AUTHORITY: <span class="hljs-number">0</span>, ADDITIONAL: <span class="hljs-number">1</span>
;; WARNING: recursion requested but <span class="hljs-keyword">not</span> available

;; OPT PSEUDOSECTION:
; EDNS: version: <span class="hljs-number">0</span>, flags:; udp: <span class="hljs-number">4096</span>
;; QUESTION SECTION:
;example.com.            IN    A

;; ANSWER SECTION:
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">23.192</span><span class="hljs-number">.228</span><span class="hljs-number">.80</span>
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">23.192</span><span class="hljs-number">.228</span><span class="hljs-number">.84</span>
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">23.215</span><span class="hljs-number">.0</span><span class="hljs-number">.136</span>
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">23.215</span><span class="hljs-number">.0</span><span class="hljs-number">.138</span>
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">96.7</span><span class="hljs-number">.128</span><span class="hljs-number">.175</span>
example.com.        <span class="hljs-number">300</span>    IN    A    <span class="hljs-number">96.7</span><span class="hljs-number">.128</span><span class="hljs-number">.198</span>

;; Query time: <span class="hljs-number">306</span> msec
;; SERVER: <span class="hljs-number">2001</span>:<span class="hljs-number">500</span>:<span class="hljs-number">8f</span>::<span class="hljs-number">53</span>#<span class="hljs-number">53</span>(a.iana-servers.net) (UDP)
;; WHEN: Sat Jun <span class="hljs-number">07</span> <span class="hljs-number">17</span>:<span class="hljs-number">34</span>:<span class="hljs-number">36</span> IST <span class="hljs-number">2025</span>
;; MSG SIZE  rcvd: <span class="hljs-number">136</span>
</code></pre>
<p>This time, we get the desired result: a list of A records (IPv4 addresses) such as <code>23.192.228.80</code>, <code>96.7.128.175</code>, and others. This step-by-step resolution—from root to TLD to authoritative servers—demonstrates how DNS works behind the scenes to translate human-readable domain names into machine-usable IP addresses.</p>
<h2 id="heading-understanding-reverse-dns-lookups">Understanding Reverse DNS Lookups</h2>
<p>Reverse DNS lookups, involve determining the domain name associated with a given IP address. This process is the opposite of a standard DNS lookup, which resolves domain names to IP addresses, and is often used for verifying the authenticity of email servers and other network communications.</p>
<p>We can explore how to achieve this by utilizing the <code>-x</code> option with the <code>dig</code> command. This allows us to retrieve the domain names associated with the IP address 8.8.8.8, which is Google's DNS server.</p>
<pre><code class="lang-plaintext">dig -x 8.8.8.8
</code></pre>
<pre><code class="lang-c">; &lt;&lt;&gt;&gt; DiG <span class="hljs-number">9.18</span><span class="hljs-number">.30</span><span class="hljs-number">-0u</span>buntu0<span class="hljs-number">.24</span><span class="hljs-number">.04</span><span class="hljs-number">.2</span>-Ubuntu &lt;&lt;&gt;&gt; -x <span class="hljs-number">8.8</span><span class="hljs-number">.8</span><span class="hljs-number">.8</span>
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: <span class="hljs-number">47927</span>
;; flags: qr rd ra; QUERY: <span class="hljs-number">1</span>, ANSWER: <span class="hljs-number">1</span>, AUTHORITY: <span class="hljs-number">0</span>, ADDITIONAL: <span class="hljs-number">1</span>

;; OPT PSEUDOSECTION:
; EDNS: version: <span class="hljs-number">0</span>, flags:; udp: <span class="hljs-number">65494</span>
;; QUESTION SECTION:
;<span class="hljs-number">8.8</span><span class="hljs-number">.8</span><span class="hljs-number">.8</span>.in-addr.arpa.        IN    PTR

;; ANSWER SECTION:
<span class="hljs-number">8.8</span><span class="hljs-number">.8</span><span class="hljs-number">.8</span>.in-addr.arpa.    <span class="hljs-number">7048</span>    IN    PTR    dns.google.

;; Query time: <span class="hljs-number">0</span> msec
;; SERVER: <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.53</span>#<span class="hljs-number">53</span>(<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.53</span>) (UDP)
;; WHEN: Sat Jun <span class="hljs-number">07</span> <span class="hljs-number">17</span>:<span class="hljs-number">25</span>:<span class="hljs-number">35</span> IST <span class="hljs-number">2025</span>
;; MSG SIZE  rcvd: <span class="hljs-number">73</span>
</code></pre>
<p>Here is the response: as you can observe, we have obtained the <a target="_blank" href="http://dns.google"><code>dns.google</code></a> domain name.</p>
<h3 id="heading-understanding-in-addrarpahttpin-addrarpa-queries">Understanding <code>.</code><a target="_blank" href="http://in-addr.arpa"><code>in-addr.arpa</code></a> Queries</h3>
<p>To find reverse domain names, we perform a process similar to using <code>dig -x</code>. This involves querying the reverse DNS for a given IP address.</p>
<p>For the address <code>96.7.128.175</code>, we use the command <code>dig</code> <a target="_blank" href="http://175.128.7.96.in-addr.arpa"><code>175.128.7.96.in-addr.arpa</code></a><code>.</code>. The key step here is reversing the order of the IP address segments and appending <a target="_blank" href="http://in-addr.arpa"><code>in-addr.arpa</code></a><code>.</code> to the end. This reversed format is necessary because the DNS system uses this structure to map IP addresses back to domain names.</p>
<pre><code class="lang-c">; &lt;&lt;&gt;&gt; DiG <span class="hljs-number">9.18</span><span class="hljs-number">.30</span><span class="hljs-number">-0u</span>buntu0<span class="hljs-number">.24</span><span class="hljs-number">.04</span><span class="hljs-number">.2</span>-Ubuntu &lt;&lt;&gt;&gt; <span class="hljs-number">175.128</span><span class="hljs-number">.7</span><span class="hljs-number">.96</span>.in-addr.arpa
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: <span class="hljs-number">16152</span>
;; flags: qr rd ra; QUERY: <span class="hljs-number">1</span>, ANSWER: <span class="hljs-number">0</span>, AUTHORITY: <span class="hljs-number">1</span>, ADDITIONAL: <span class="hljs-number">1</span>

;; OPT PSEUDOSECTION:
; EDNS: version: <span class="hljs-number">0</span>, flags:; udp: <span class="hljs-number">65494</span>
;; QUESTION SECTION:
;<span class="hljs-number">175.128</span><span class="hljs-number">.7</span><span class="hljs-number">.96</span>.in-addr.arpa.    IN    A

;; AUTHORITY SECTION:
in-addr.arpa.        <span class="hljs-number">1800</span>    IN    SOA    ns1.reverse.deploy.akamaitechnologies.com. hostmaster.akamai.com. <span class="hljs-number">1582134113</span> <span class="hljs-number">90000</span> <span class="hljs-number">90000</span> <span class="hljs-number">90000</span> <span class="hljs-number">180</span>

;; Query time: <span class="hljs-number">101</span> msec
;; SERVER: <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.53</span>#<span class="hljs-number">53</span>(<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.53</span>) (UDP)
;; WHEN: Sat Jun <span class="hljs-number">07</span> <span class="hljs-number">17</span>:<span class="hljs-number">37</span>:<span class="hljs-number">40</span> IST <span class="hljs-number">2025</span>
;; MSG SIZE  rcvd: <span class="hljs-number">149</span>
</code></pre>
<p><code>dig -x</code> command internally uses the <code>.</code><a target="_blank" href="http://in-addr.arpa"><code>in-addr.arpa</code></a> queries. To confirm this, we can examine the source code of the <code>dig</code> command.</p>
<pre><code class="lang-c"><span class="hljs-function"><span class="hljs-keyword">isc_result_t</span>
<span class="hljs-title">get_reverse</span><span class="hljs-params">(<span class="hljs-keyword">char</span> *reverse, <span class="hljs-keyword">size_t</span> len, <span class="hljs-keyword">char</span> *value, <span class="hljs-keyword">isc_boolean_t</span> ip6_int,
        <span class="hljs-keyword">isc_boolean_t</span> strict)</span>
</span>{
    <span class="hljs-keyword">int</span> r;
    <span class="hljs-keyword">isc_result_t</span> result;
    <span class="hljs-keyword">isc_netaddr_t</span> addr;

    addr.family = AF_INET6;
    r = inet_pton(AF_INET6, value, &amp;addr.type.in6);
    <span class="hljs-keyword">if</span> (r &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-comment">/* This is a valid IPv6 address. */</span>
        <span class="hljs-keyword">dns_fixedname_t</span> fname;
        <span class="hljs-keyword">dns_name_t</span> *name;
        <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span> options = <span class="hljs-number">0</span>;

        <span class="hljs-keyword">if</span> (ip6_int)
            options |= DNS_BYADDROPT_IPV6INT;
        dns_fixedname_init(&amp;fname);
        name = dns_fixedname_name(&amp;fname);
        result = dns_byaddr_createptrname2(&amp;addr, options, name);
        <span class="hljs-keyword">if</span> (result != ISC_R_SUCCESS)
            <span class="hljs-keyword">return</span> (result);
        dns_name_format(name, reverse, (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span>)len);
        <span class="hljs-keyword">return</span> (ISC_R_SUCCESS);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">/*
         * Not a valid IPv6 address.  Assume IPv4.
         * If 'strict' is not set, construct the
         * in-addr.arpa name by blindly reversing
         * octets whether or not they look like integers,
         * so that this can be used for RFC2317 names
         * and such.
         */</span>
        <span class="hljs-keyword">char</span> *p = reverse;
        <span class="hljs-keyword">char</span> *end = reverse + len;
        <span class="hljs-keyword">if</span> (strict &amp;&amp; inet_pton(AF_INET, value, &amp;addr.type.in) != <span class="hljs-number">1</span>)
            <span class="hljs-keyword">return</span> (DNS_R_BADDOTTEDQUAD);
        result = reverse_octets(value, &amp;p, end);
        <span class="hljs-keyword">if</span> (result != ISC_R_SUCCESS)
            <span class="hljs-keyword">return</span> (result);
        <span class="hljs-comment">/* Append .in-addr.arpa. and a terminating NUL. */</span>
        result = append(<span class="hljs-string">".in-addr.arpa."</span>, <span class="hljs-number">15</span>, &amp;p, end);
        <span class="hljs-keyword">if</span> (result != ISC_R_SUCCESS)
            <span class="hljs-keyword">return</span> (result);
        <span class="hljs-keyword">return</span> (ISC_R_SUCCESS);
    }
}
</code></pre>
<h2 id="heading-understanding-the-resolution-of-subdomains">Understanding the Resolution of Subdomains</h2>
<p>A subdomain is a distinct section of a main domain, allowing for the creation of separate websites or web services under the primary domain name. For example, "<a target="_blank" href="http://blog.example.com">blog.example.com</a>" is a subdomain of "<a target="_blank" href="http://example.com">example.com</a>," enabling the hosting of a blog on a different URL while maintaining the main domain's branding.</p>
<pre><code class="lang-mermaid">graph TD
    A[Client] --&gt;|DNS Query| B[Local DNS Server]
    B --&gt;|Recursive Query| C[Root DNS Server]
    C --&gt;|Referral| D[TLD DNS Server]
    D --&gt;|Referral| E[Authoritative DNS Server]
    E --&gt;|DNS Response| D
    D --&gt;|DNS Response| C
    C --&gt;|DNS Response| B
    B --&gt;|DNS Response| A
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#bbf,stroke:#f66,stroke-width:2px
    style C fill:#bbf,stroke:#f66,stroke-width:2px
    style D fill:#bbf,stroke:#f66,stroke-width:2px
    style E fill:#bbf,stroke:#f66,stroke-width:2px
</code></pre>
<h4 id="heading-no-delegation">No Delegation</h4>
<hr />
<p>In a non-delegated subdomain, the DNS records for the subdomain are managed by the parent domain's DNS servers. For instance, if <a target="_blank" href="http://blog.example.com"><code>blog.example.com</code></a> is a non-delegated subdomain, the DNS records for <code>blog</code> are handled by the DNS servers responsible for <a target="_blank" href="http://example.com"><code>example.com</code></a>. This setup simplifies management but can centralize the load on the parent domain's servers.</p>
<pre><code class="lang-c">example.com       → handled by ns1.dnsprovider.com
blog.example.com  → also handled by ns1.dnsprovider.com
</code></pre>
<h4 id="heading-delegated-subdomain">Delegated Subdomain</h4>
<hr />
<p>A delegated subdomain, on the other hand, has its own set of DNS servers. For example, if <a target="_blank" href="http://blog.example.com"><code>blog.example.com</code></a> is a delegated subdomain, it will have its own DNS servers that manage its records independently of <a target="_blank" href="http://example.com"><code>example.com</code></a>. This approach distributes the DNS load and allows for more granular control over the subdomain's DNS settings, enhancing flexibility and performance.</p>
<pre><code class="lang-c">example.com              → handled by ns1.dnsprovider.com
internal.example.com     → delegated to ns1.internaldns.net
</code></pre>
<h2 id="heading-dns-records-syntax">DNS Records Syntax</h2>
<p>DNS records follow a specific syntax to define various types of data. The basic structure is:</p>
<ul>
<li><p><code>&lt;name&gt;</code>: The domain name for which the record is valid.</p>
</li>
<li><p><code>&lt;ttl&gt;</code>: Time to Live, indicating how long the record should be cached.</p>
</li>
<li><p><code>&lt;class&gt;</code>: The class of the DNS data, typically <code>IN</code> for Internet.</p>
</li>
<li><p><code>&lt;type&gt;</code>: The type of DNS record, such as <code>A</code>, <code>MX</code>, <code>CNAME</code>, etc.</p>
</li>
<li><p><code>&lt;rdlength&gt;</code>: The length of the RDATA field in bytes.</p>
</li>
<li><p><code>&lt;rdata&gt;</code>: The actual data for the record, varying by type (e.g., IP address for <code>A</code> records).</p>
</li>
</ul>
<p>This syntax ensures that DNS queries and responses are correctly interpreted by DNS servers and clients.</p>
<h1 id="heading-dns-record-types">DNS Record Types</h1>
<p>DNS (Domain Name System) records are essential for translating human-readable domain names into IP addresses and providing other critical information. Here are some of the most common types of DNS records:</p>
<h2 id="heading-a-record">A Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Maps a domain name to an IPv4 address.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://example.com"><code>example.com</code></a><code>. IN A 192.0.2.1</code></p>
</li>
</ul>
<h2 id="heading-soa-record">SOA Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Specifies the primary name server for a domain and provides administrative information.</p>
</li>
<li><p><strong>Example</strong>:</p>
<pre><code class="lang-plaintext">  example.com. IN SOA ns1.example.com. admin.example.com. (
      2023101001 ; Serial
      3600       ; Refresh
      1800       ; Retry
      1209600    ; Expire
      3600       ; Minimum TTL
  )
</code></pre>
</li>
</ul>
<h2 id="heading-mx-record">MX Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Specifies the mail servers responsible for receiving email on behalf of a domain.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://example.com"><code>example.com</code></a><code>. IN MX 10</code> <a target="_blank" href="http://mail.example.com"><code>mail.example.com</code></a><code>.</code></p>
</li>
</ul>
<h2 id="heading-ns-record">NS Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Specifies the authoritative name servers for a domain.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://example.com"><code>example.com</code></a><code>. IN NS</code> <a target="_blank" href="http://ns1.example.com"><code>ns1.example.com</code></a><code>.</code></p>
</li>
</ul>
<h2 id="heading-cname-record">CNAME Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Aliases one domain name to another.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://www.example.com"><code>www.example.com</code></a><code>. IN CNAME</code> <a target="_blank" href="http://example.com"><code>example.com</code></a><code>.</code></p>
</li>
</ul>
<h2 id="heading-ptr-record">PTR Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Maps an IPv4 address to a domain name (reverse DNS lookup).</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://1.2.0.192.in-addr.arpa"><code>1.2.0.192.in-addr.arpa</code></a><code>. IN PTR</code> <a target="_blank" href="http://example.com"><code>example.com</code></a><code>.</code></p>
</li>
</ul>
<h2 id="heading-hinfo-record">HINFO Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Provides information about the hardware and operating system of a host.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://example.com"><code>example.com</code></a><code>. IN HINFO "PC" "Windows 10"</code></p>
</li>
</ul>
<h2 id="heading-txt-record">TXT Record</h2>
<ul>
<li><p><strong>Purpose</strong>: Holds text information for sources outside your domain.</p>
</li>
<li><p><strong>Example</strong>: <a target="_blank" href="http://example.com"><code>example.com</code></a><code>. IN TXT "v=spf1 include:_</code><a target="_blank" href="http://spf.google.com"><code>spf.google.com</code></a> <code>~all"</code></p>
</li>
</ul>
<h2 id="heading-dns-zone-file">DNS Zone File</h2>
<p>A DNS zone file is a text file that contains mappings between domain names and IP addresses, facilitating the translation of human-readable domain names into numerical IP addresses that computers use to identify each other on the network. It is organized into records, each specifying a particular type of information, such as A records for IPv4 addresses, AAAA records for IPv6 addresses, and MX records for mail servers. Zone files are essential for the functioning of the Domain Name System (DNS), enabling efficient and reliable domain name resolution across the internet.</p>
<pre><code class="lang-plaintext">$TTL 3600
@       IN  SOA ns1.example.com. admin.example.com. (
                2025060701 ; Serial
                3600       ; Refresh
                1800       ; Retry
                1209600    ; Expire
                86400 )    ; Minimum TTL

        IN  NS   ns1.example.com.
        IN  NS   ns2.example.com.
@       IN  A    192.0.2.1
www     IN  CNAME example.com.
mail    IN  A    192.0.2.2
@       IN  MX   10 mail.example.com.
</code></pre>
<p>A DNS zone file is a text file that contains mappings between domain names and IP addresses, facilitating the translation of human-readable domain names into numerical IP addresses that computers use to identify each other on a network. It is organized into records, each specifying details like the domain name, record type (e.g., A, CNAME, MX), and corresponding values. Zone files are essential for DNS servers to resolve queries efficiently and direct traffic to the correct destinations. They are typically managed by domain administrators to ensure accurate and up-to-date DNS configurations.</p>
<h2 id="heading-attacks-on-dns">Attacks on DNS</h2>
<h3 id="heading-denial-of-service">Denial Of Service</h3>
<p><strong>Denial of Service (DoS) attacks against DNS servers</strong> aim to overwhelm the server with excessive traffic, preventing it from responding to legitimate requests. This disrupts the translation of domain names to IP addresses, causing widespread internet outages and making websites and services inaccessible.</p>
<h3 id="heading-dns-cache-poisoning">DNS cache poisoning</h3>
<p>DNS cache poisoning occurs when an attacker corrupts a DNS resolver's cache with false information, redirecting users to malicious websites. This manipulation can lead to various security issues, such as phishing attacks or data theft, by exploiting the trust users place in legitimate domain names.</p>
<h2 id="heading-dnssec">DNSSEC</h2>
<p>DNSSEC (Domain Name System Security Extensions) is a suite of specifications designed to enhance the security of the Domain Name System (DNS) by enabling DNS responses to be validated. It adds cryptographic signatures to DNS data, helping to protect against certain types of attacks, such as DNS spoofing and cache poisoning.</p>
]]></content:encoded></item><item><title><![CDATA[A Simple HTTP Server in C]]></title><description><![CDATA[Directory Structure and Makefile
Directory Structure
.
├── build
├── include
├── Makefile
├── README.md
└── src
    └── main.c

The directory structure is organized as follows:

build: This directory is intended to hold the compiled output of the pro...]]></description><link>https://blogs.praful.dev/a-simple-http-server-in-c</link><guid isPermaLink="true">https://blogs.praful.dev/a-simple-http-server-in-c</guid><category><![CDATA[C]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Praful M]]></dc:creator><pubDate>Sat, 12 Jul 2025 19:24:37 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-directory-structure-and-makefile">Directory Structure and Makefile</h2>
<h3 id="heading-directory-structure">Directory Structure</h3>
<pre><code class="lang-plaintext">.
├── build
├── include
├── Makefile
├── README.md
└── src
    └── main.c
</code></pre>
<p>The directory structure is organized as follows:</p>
<ul>
<li><p><strong>build</strong>: This directory is intended to hold the compiled output of the project. It typically contains the executable files and any intermediate object files generated during the build process.</p>
</li>
<li><p><strong>include</strong>: This folder is used to store header files (.h) that contain declarations for the functions and variables used in the source code. These headers are included in the source files to provide necessary definitions and interfaces.</p>
</li>
<li><p><strong>Makefile</strong>: This file contains instructions for the build process. It defines rules and dependencies for compiling the source code into an executable program. The Makefile automates the compilation process, making it easier to build the project.</p>
</li>
<li><p><a target="_blank" href="http://README.md"><strong>README.md</strong></a>: This markdown file provides an overview of the project. It usually includes information about the project's purpose, how to set it up, how to build it, and any other relevant details that users or developers might need to know.</p>
</li>
<li><p><strong>src</strong>: This directory contains the source code files for the project. It is where the main implementation of the program resides.</p>
</li>
</ul>
<h3 id="heading-makefile">Makefile</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Compiler</span>
CC = gcc

<span class="hljs-comment"># Directories</span>
SRC_DIR = src
INC_DIR = include
BUILD_DIR = build

<span class="hljs-comment"># Files</span>
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
TARGET = $(BUILD_DIR)/main

<span class="hljs-comment"># Flags</span>
CFLAGS = -I$(INC_DIR) -Wall -Wextra -g

<span class="hljs-comment"># Rules</span>
all: $(TARGET)
    $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
    $(CC) $(CFLAGS) -c $&lt; -o <span class="hljs-variable">$@</span>
    $(TARGET): $(OBJS)
    $(CC) $(CFLAGS) $^ -o <span class="hljs-variable">$@</span>

$(BUILD_DIR):
    mkdir -p $(BUILD_DIR)

run: $(TARGET)
    ./$(TARGET)

clean:
rm -rf $(BUILD_DIR)

.PHONY: all clean
</code></pre>
<p>A Makefile simplifies our workflow. Instead of typing out a lengthy command with all the necessary compiler flags or pressing the up arrow on your terminal, we can predefine the commands and execute them using simple commands like <code>make run</code>, <code>make clean</code>, etc.</p>
<h2 id="heading-understanding-file-descriptors">Understanding File Descriptors</h2>
<p>File descriptors are unique identifiers used by the operating system to access files or other input/output resources. They enable programs to read from or write to these resources efficiently. Each open file or resource is associated with a specific file descriptor, typically an Integer.</p>
<pre><code class="lang-c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;fcntl.h&gt;</span></span>

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{

    <span class="hljs-keyword">int</span> filefd = open(<span class="hljs-string">"test.txt"</span>, O_WRONLY | O_CREAT | O_TRUNC, <span class="hljs-number">0644</span>);
    <span class="hljs-keyword">if</span> (filefd &lt; <span class="hljs-number">0</span>) {
        perror(<span class="hljs-string">"Failed to open file"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"File descriptor: %d\n"</span>, filefd);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>In this program, we open a file described by <code>test.txt</code> using the options <code>O_WRONLY | O_CREAT | O_TRUNC</code>. Here's a brief explanation of these options:</p>
<ul>
<li><p><code>O_WRONLY</code>: Opens the file for writing only.</p>
</li>
<li><p><code>O_CREAT</code>: Creates the file if it does not exist.</p>
</li>
<li><p><code>O_TRUNC</code>: Truncates the file to zero length if it already exists.</p>
</li>
</ul>
<p>These options are bitwise OR'd together. They are defined in the <code>fcntl.h</code> header file and are essentially binary numbers. We OR these flags and pass the resulting integer to the <code>open</code> system call. Additionally, we can set the file permissions to <code>0644</code>, which is the same format used with the <code>chmod</code> command. The leading zero in 0644 signifies that the number is in octal format.</p>
<p>You can use <code>Ctrl + Click</code> on the flags to navigate to the file located at <code>/usr/include/x86_64-linux-gnu/bits/fcntl.h</code>.</p>
<pre><code class="lang-c"><span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> O_ACCMODE       0003</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> O_RDONLY         00</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> O_WRONLY         01</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> O_RDWR             02</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_CREAT</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_CREAT       0100    <span class="hljs-comment">/* Not fcntl.  */</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_EXCL</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_EXCL           0200    <span class="hljs-comment">/* Not fcntl.  */</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_NOCTTY</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_NOCTTY       0400    <span class="hljs-comment">/* Not fcntl.  */</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_TRUNC</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_TRUNC      01000    <span class="hljs-comment">/* Not fcntl.  */</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_APPEND</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_APPEND      02000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_NONBLOCK</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_NONBLOCK      04000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_NDELAY</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_NDELAY    O_NONBLOCK</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_SYNC</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_SYNC           04010000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> O_FSYNC        O_SYNC</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> O_ASYNC</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> O_ASYNC     020000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_LARGEFILE</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_LARGEFILE    0100000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_DIRECTORY</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_DIRECTORY    0200000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_NOFOLLOW</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_NOFOLLOW    0400000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_CLOEXEC</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_CLOEXEC   02000000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_DIRECT</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_DIRECT     040000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_NOATIME</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_NOATIME   01000000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_PATH</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_PATH     010000000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_DSYNC</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_DSYNC     010000</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">ifndef</span> __O_TMPFILE</span>
<span class="hljs-meta"># <span class="hljs-meta-keyword">define</span> __O_TMPFILE   (020000000 | __O_DIRECTORY)</span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
</code></pre>
<p>Above, you can see that we have defined an octal number, which we can pass using the <code>|</code> operator and send it to the <code>open</code> syscall.</p>
<h2 id="heading-sockets">Sockets</h2>
<h3 id="heading-introduction">Introduction</h3>
<p>Sockets are endpoints for communication between two machines. They enable data exchange over a network using protocols like TCP or UDP. Sockets are fundamental in network programming, allowing applications to send and receive data.</p>
<blockquote>
<p>The primary distinction between normal file descriptors and socket descriptors lies in their binding behavior. When you use the <code>open</code> function in C to access a file, you receive a file descriptor that is directly bound to a specific file or device on the system. In contrast, when you create a socket and receive a file descriptor, it is not automatically bound to any port. You must manually bind the socket descriptor to a port using additional functions.</p>
</blockquote>
<h3 id="heading-socket-creation">Socket Creation</h3>
<p>In networking, socket creation is the initial step in establishing a connection between two devices. It involves generating a unique endpoint for communication, typically using a combination of IP address and port number. This process is fundamental in both client-server and peer-to-peer communication models.</p>
<pre><code class="lang-c"><span class="hljs-comment">// Create a socket</span>
<span class="hljs-keyword">int</span> sockfd = socket(AF_INET, SOCK_STREAM, <span class="hljs-number">0</span>);
<span class="hljs-keyword">if</span> (sockfd &lt; <span class="hljs-number">0</span>) {
    perror(<span class="hljs-string">"Error opening socket"</span>);
    <span class="hljs-built_in">exit</span>(<span class="hljs-number">1</span>);
}
</code></pre>
<p>The syntax for creating a socket is shown above. It accepts three arguments and returns a descriptor.</p>
<p>The initial parameter is referred to as the <strong>Protocol family</strong>. There are numerous families, including AF_INET, AF_BLUETOOTH, and AF_INET6. This parameter determines the fundamental type of socket being created. For instance, AF_INET is used for IPv4 connections.</p>
<p>The subsequent parameter is known as the <strong>Socket Type</strong>, with two primary options: <code>SOCK_DGRAM</code> and <code>SOCK_STREAM</code>. <code>SOCK_DGRAM</code> refers to datagrams, not exclusively UDP, as there are various types of datagrams, with UDP being one of them. This parameter defines a protocol class, while the specific protocol is determined by the next parameter. It's important to note that <code>SOCK_STREAM</code> represents an ordered, reliable stream, whereas <code>SOCK_DGRAM</code> signifies an unordered, unreliable stream.</p>
<p>The final parameter is named Protocol, and it specifies the particular protocol to be used. For instance, if we select SOCK_DGRAM, we can utilize the UDP protocol, UDPLite, or ICMPv6. It's important to note that you cannot use SOCK_STREAM with a protocol that belongs to the SOCK_DGRAM class, such as UDP or UDPLite, and vice versa.</p>
<blockquote>
<p>Honestly, I'm aware that recalling protocol numbers for protocols can be challenging, and it's easy to forget or mix them up. To simplify this, we can utilize a function called <code>getprotobyname</code>. This function accepts the protocol name as a parameter, like <code>tcp</code>, and returns a <code>protoent</code> structure. From this structure, we can access the protocol number using <code>protoent-&gt;p_proto</code>.</p>
</blockquote>
<pre><code class="lang-c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">protoent</span> *<span class="hljs-title">proto</span>
<span class="hljs-title">proto</span> = <span class="hljs-title">getprotobyname</span>('<span class="hljs-title">tcp</span>')
<span class="hljs-title">sockfd</span> = <span class="hljs-title">socket</span>(<span class="hljs-title">AF_INET</span>, <span class="hljs-title">SOCK_STREAM</span>, <span class="hljs-title">proto</span>-&gt;<span class="hljs-title">p_proto</span>);</span>
</code></pre>
<h3 id="heading-binding-to-an-address-and-port">Binding to an Address and Port</h3>
<p>Binding to an address and port refers to the process of assigning a specific network address and port number to a network socket. This allows a program to listen for incoming data or send data to a particular destination. It's a fundamental concept in network programming, enabling communication between different devices and applications.</p>
<pre><code class="lang-c"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">bind</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sockfd, <span class="hljs-keyword">const</span> struct sockaddr_in *addr, <span class="hljs-keyword">socklen_t</span> addrlen)</span></span>;
</code></pre>
<p>To utilize the <code>bind</code> function, we must supply it with our socket file descriptor and a structure known as <code>sockaddr</code>. Let's take a closer look at the <code>sockaddr</code> structure.</p>
<pre><code class="lang-c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sockaddr_in</span> {</span>
    <span class="hljs-keyword">sa_family_t</span>    sin_family;  <span class="hljs-comment">// Always AF_INET</span>
    <span class="hljs-keyword">in_port_t</span>      sin_port;    <span class="hljs-comment">// Port number (must use htons())</span>
    <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">in_addr</span> <span class="hljs-title">sin_addr</span>;</span>    <span class="hljs-comment">// IP address</span>
    <span class="hljs-keyword">char</span>           sin_zero[<span class="hljs-number">8</span>]; <span class="hljs-comment">// Padding (unused, just fill with 0s)</span>
};
</code></pre>
<p>Let's proceed to construct a <code>sockaddr_in</code> structure.</p>
<pre><code class="lang-c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sockaddr_in</span> <span class="hljs-title">server_addr</span>;</span>
</code></pre>
<p>When we create it, it might contain garbage values, so we need to reset all of them to 0. We can achieve this using the <code>memset</code> function. We need to provide three things: the struct, the value to write, and the size.</p>
<pre><code class="lang-c"><span class="hljs-built_in">memset</span>(&amp;server_addr, <span class="hljs-number">0</span>, <span class="hljs-keyword">sizeof</span>(server_addr));
</code></pre>
<p>Let's configure the server address to bind to.</p>
<pre><code class="lang-c">server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(<span class="hljs-number">8080</span>);
server_addr.sin_addr.s_addr = inet_addr(<span class="hljs-string">"0.0.0.0"</span>);
</code></pre>
<p>The <code>sin_family</code> must be set to <code>AF_INET</code> exclusively because we are utilizing <code>sockaddr_in</code>, which is designed for IPv4 communication. Therefore, no other value can be used for <code>sin_family</code></p>
<p><code>sin_port</code> This can be configured to any port, but avoid using well-known ports such as 22.</p>
<p><code>htons</code> converts a 16-bit unsigned short from host byte order to network byte order. It ensures that the byte order is consistent across different systems when transmitting data over a network. This function is crucial for network programming to maintain data integrity.</p>
<p><strong>htons -&gt; Host to Network Short</strong></p>
<p>To understand the necessity, consider that different systems may employ either little-endian or big-endian formats. However, data transmitted over networks consistently uses big-endian. Consequently, we utilize the host-to-network byte order function, commonly abbreviated as <code>htons</code>.</p>
<p>Finally, we can configure <code>sin_addr</code> and its parameter <code>s_addr</code> using <code>inet_addr</code>. The <code>inet_addr</code> function takes an IPv4 string as its parameter.</p>
<p>We can also configure <code>sin_addr.s_addr</code> to <code>INADDR_ANY</code>, which allows the system to accept connections on any available network interface.</p>
<h3 id="heading-iana-port-number-ranges">IANA Port Number Ranges</h3>
<p>There are three ranges of port numbers defined by the Internet Assigned Numbers Authority (IANA):</p>
<ol>
<li><p><strong>Well-Known Ports (0-1023)</strong></p>
<ul>
<li><p>These ports are reserved for specific protocols such as HTTP, SSH, and DNS.</p>
</li>
<li><p>We must avoid binding sockets to ports within this range.</p>
</li>
</ul>
</li>
<li><p><strong>Registered Ports (1024-49151)</strong></p>
<ul>
<li>These ports are available for use in binding and other operations.</li>
</ul>
</li>
<li><p><strong>Dynamic/Ephemeral Ports (49152-65535)</strong></p>
<ul>
<li>These ports are used by the system as ephemeral ports during communication.</li>
</ul>
</li>
</ol>
<h3 id="heading-listening-on-a-socket">Listening on a Socket</h3>
<p>The <code>listen()</code> function in network programming is used to mark a socket as a passive socket, indicating that it will be used to accept incoming connection requests. This function is typically called on a server-side socket to enable it to listen for incoming connections from client sockets. The <code>listen()</code> function takes a backlog parameter, which specifies the maximum number of pending connections that can be queued before new connection requests are rejected.</p>
<pre><code class="lang-c">listen(sockfd, <span class="hljs-number">5</span>)
</code></pre>
<p>The initial parameter represents the socket file descriptor, while the second parameter denotes the size of the queue.</p>
<ul>
<li><p>Returns <code>0</code> on success.</p>
</li>
<li><p>Returns <code>-1</code> on failure.</p>
</li>
</ul>
<h3 id="heading-accepting-a-connection">Accepting a Connection</h3>
<p>Accepting a connection involves using the <code>accept()</code> function, which is typically called on a socket that is already bound to a specific port and is listening for incoming connections. This function returns a new socket file descriptor that can be used to communicate with the connected client. The <code>accept()</code> function is usually used in conjunction with <code>bind()</code> and <code>listen()</code> functions to set up the server socket.</p>
<pre><code class="lang-c"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">accept</span><span class="hljs-params">(<span class="hljs-keyword">int</span> sockfd, struct sockaddr *addr, <span class="hljs-keyword">socklen_t</span> *addrlen)</span></span>;
</code></pre>
<p>To handle incoming connections, you need to pass the socket file descriptor to the <code>accept</code> function. For each accepted connection, you must store the client's <code>sockaddr</code> information. To achieve this, you'll need to create a new <code>sockaddr</code> structure and pass it along with its length as the next two parameters to the <code>accept</code> function.</p>
<pre><code class="lang-c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sockaddr_in</span> <span class="hljs-title">client_addr</span>;</span> 
<span class="hljs-keyword">socklen_t</span> client_len = <span class="hljs-keyword">sizeof</span>(client_addr);


<span class="hljs-keyword">int</span> newsockfd = accept(sockfd, (struct sockaddr *)&amp;client_addr, &amp;client_len);
<span class="hljs-keyword">if</span> (newsockfd &lt; <span class="hljs-number">0</span>) {
    perror(<span class="hljs-string">"accept"</span>);
    close(sockfd);
    <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
}
</code></pre>
<p>You should be aware that the <code>accept</code> function call is a blocking call. If you invoke the <code>accept</code> call, it will remain in a blocked state until a connection is received and closed.</p>
<pre><code class="lang-c"><span class="hljs-built_in">printf</span>(<span class="hljs-string">"Accepted connection from %s:%d\n"</span>,
        inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *response = <span class="hljs-string">"HTTP/1.1 200 OK\r\n"</span>
                        <span class="hljs-string">"Content-Type: text/plain\r\n"</span>
                        <span class="hljs-string">"Content-Length: 13\r\n"</span>
                        <span class="hljs-string">"\r\n"</span>
                        <span class="hljs-string">"Hello, World!"</span>;
write(newsockfd, response, <span class="hljs-built_in">strlen</span>(response));
close(newsockfd);
</code></pre>
<p>Upon accepting a connection, the details of the connection, such as the client's IP address and port, are stored in the <code>sockadd</code> structure that we provided. These details can be retrieved from this structure.</p>
<p>Next, we'll create an HTTP 1.1 response to send back to the client. For now, we'll manually send a simple "hello world" string. Don't worry about the HTTP protocol details; it's text-based, and you can understand what's happening just by reading the response value.</p>
<p>Currently, we employ the <code>write</code> call in a manner similar to writing to any other file descriptor. We pass the file descriptor, the buffer, and the length to write.</p>
<p>We then terminate the connection.</p>
<h3 id="heading-curl-and-check"><code>curl</code> and Check</h3>
<p>Let's now utilize the <code>curl</code> command to establish a connection with the server.</p>
<pre><code class="lang-bash">razor@beast:~$ curl localhost:8080
Hello, World!
</code></pre>
<p>Here's what we've got: the "hello world" text displayed in the terminal. We've just created a basic HTTP server using C.</p>
<h3 id="heading-accepting-connections-with-a-while-loop">Accepting Connections with a <code>while</code> Loop</h3>
<p>You may have noticed that when you attempt to use <code>curl</code> again, the connection fails because the server shuts down after the previous unsuccessful connection. This happens because the <code>accept</code> primitive is a blocking call. It listens for a connection the first time, and once it receives one, it executes the code and exits, causing the entire program to terminate. To prevent this, you can wrap the entire accept connection code in an infinite <code>while</code> loop.</p>
<pre><code class="lang-c"><span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>){
    <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sockaddr_in</span> <span class="hljs-title">client_addr</span>;</span> 
    <span class="hljs-keyword">socklen_t</span> client_len = <span class="hljs-keyword">sizeof</span>(client_addr);


    <span class="hljs-keyword">int</span> newsockfd = accept(sockfd, (struct sockaddr *)&amp;client_addr, &amp;client_len);
    <span class="hljs-keyword">if</span> (newsockfd &lt; <span class="hljs-number">0</span>) {
        perror(<span class="hljs-string">"accept"</span>);
        close(sockfd);
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

    <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Accepted connection from %s:%d\n"</span>,
           inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> *response = <span class="hljs-string">"HTTP/1.1 200 OK\r\n"</span>
                           <span class="hljs-string">"Content-Type: text/plain\r\n"</span>
                           <span class="hljs-string">"Content-Length: 13\r\n"</span>
                           <span class="hljs-string">"\r\n"</span>
                           <span class="hljs-string">"Hello, World!"</span>;
    write(newsockfd, response, <span class="hljs-built_in">strlen</span>(response));
    close(newsockfd);

}
</code></pre>
<p>When a connection request is received, the <code>accept</code> call will pause and wait. Upon arrival of a connection, the associated code runs, generating a response. Due to the infinite <code>while</code> loop, <code>accept</code> is called again, causing the process to pause once more waiting for other connections.</p>
]]></content:encoded></item><item><title><![CDATA[Getting Started With Docker For Microservices]]></title><description><![CDATA[Introduction to Docker


Docker is a platform that enables the creation, deployment, and management of applications within lightweight, portable containers. These containers encapsulate an application and its dependencies, ensuring consistent behavio...]]></description><link>https://blogs.praful.dev/getting-started-with-docker-for-microservices</link><guid isPermaLink="true">https://blogs.praful.dev/getting-started-with-docker-for-microservices</guid><category><![CDATA[Docker]]></category><category><![CDATA[Microservices]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Praful M]]></dc:creator><pubDate>Sat, 12 Jul 2025 19:20:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752348608497/167a8a9f-d3fc-4f74-9828-eb25352eb722.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction-to-docker">Introduction to Docker</h2>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347866521/202e561a-95b7-4daa-b043-a59e12c33e77.png" alt class="image--center mx-auto" /></p>
<p>Docker is a platform that enables the creation, deployment, and management of applications within lightweight, portable containers. These containers encapsulate an application and its dependencies, ensuring consistent behavior across different computing environments. This approach simplifies the process of developing, shipping, and running applications, enhancing efficiency and reliability.</p>
<h2 id="heading-installing-the-docker-engine">Installing the Docker Engine</h2>
<hr />
<p>For installation information, consult the official documentation. <a target="_blank" href="https://docs.docker.com/engine/install/">https://docs.docker.com/engine/install/</a></p>
<h2 id="heading-hello-world-of-docker">Hello World of Docker</h2>
<hr />
<p>In Docker, to execute a "hello-world" container, you simply need to run the following command:</p>
<pre><code class="lang-bash">docker run hello-world
</code></pre>
<p>This action will initiate the creation and startup of a container.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347886761/c0d2ca85-db02-470f-847c-68379754e062.png" alt class="image--center mx-auto" /></p>
<p>If you see output similar to this, your Docker installation was successful.</p>
<h2 id="heading-docker-images">Docker Images</h2>
<hr />
<p>Docker images are lightweight, standalone, and executable software packages that include everything needed to run a piece of software, such as code, libraries, and system tools. They serve as templates for creating Docker containers, ensuring consistent environments across different systems.</p>
<p>let us list what available docker images we can use this command</p>
<pre><code class="lang-bash">docker images
</code></pre>
<p>We obtain the following output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347894667/cab10024-bf70-4e82-86dc-0d8ddb0611ee.png" alt class="image--center mx-auto" /></p>
<p>As observed, there is an image in Docker called "hello-world." When we executed the command:</p>
<pre><code class="lang-bash">docker run hello-world
</code></pre>
<p>the Docker client on the system retrieves the image from a container registry. By default, if no registry is specified, it fetches the image from Docker Hub, located at <a target="_blank" href="http://hub.docker.com">hub.docker.com</a>, and then runs it.</p>
<p>Although <a target="_blank" href="http://hub.docker.com"><code>hub.docker.com</code></a> is the default, there are numerous container registries such as GitHub's and Google's.</p>
<p>Let's pull a <code>hello-world</code> image from the Google registry.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347910960/44857d6f-1141-4a34-afc3-8b864047945f.png" alt class="image--center mx-auto" /></p>
<p><strong>What is a Container Registry?</strong></p>
<p>A container registry is a storage and distribution system for named container images. It allows you to store, manage, and distribute Docker images. Here are a few examples:</p>
<p>🔹 <strong>Docker Hub</strong> – The most widely used registry, often compared to YouTube for Docker images. 🔹 <strong>GitHub Container Registry (GHCR)</strong> – Integrated with GitHub projects for seamless container management. 🔹 <strong>Google Artifact Registry (public)</strong> – Occasionally hosts public images from Google.</p>
<h3 id="heading-building-images-using-dockerfile">Building Images using Dockerfile</h3>
<hr />
<p>Let's attempt to create an image that includes everything necessary to run a specific software, similar to existing images like those for Nginx or Memcached. For example, consider a Python project that has a <code>requirements.txt</code> file. The image will already have all the required Python dependencies installed, so all we need to do is run the application.</p>
<h4 id="heading-building-the-python-application">Building The Python Application</h4>
<hr />
<p>First, create a folder named <code>simple-api-server</code> and navigate into it using the following command:</p>
<pre><code class="lang-bash">mkdir simple-api-server &amp;&amp; <span class="hljs-built_in">cd</span> simple-api-server
</code></pre>
<p>This command accomplishes two tasks:</p>
<ol>
<li><p>Creates a new directory called <code>simple-api-server</code>.</p>
</li>
<li><p>Changes the current working directory to <code>simple-api-server</code>.</p>
</li>
</ol>
<p>Next, let's set up a basic Python Flask server that returns a response.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"hello"</span> : <span class="hljs-string">"world"</span>
}
</code></pre>
<h5 id="heading-setup-venvoptional">Setup venv(Optional)</h5>
<hr />
<ol>
<li><p><strong>Create a Virtual Environment</strong></p>
<pre><code class="lang-sh"> python3 -m venv .venv
</code></pre>
</li>
<li><p><strong>Activate the Virtual Environment</strong></p>
<pre><code class="lang-sh"> <span class="hljs-built_in">source</span> .venv/bin/activate
</code></pre>
</li>
<li><p><strong>Install Flask</strong></p>
</li>
</ol>
<pre><code class="lang-shell">    pip install flask
</code></pre>
<h5 id="heading-coding-the-mainpyhttpmainpy">Coding the <a target="_blank" href="http://main.py"><code>main.py</code></a></h5>
<hr />
<p>Here's what the code for that Python application might look like. We'll create a file called <a target="_blank" href="http://main.py"><code>main.py</code></a> and add the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask, jsonify

app = Flask(__name__)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello_world</span>():</span>
    <span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">"hello"</span>: <span class="hljs-string">"world"</span>})

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    app.run(debug=<span class="hljs-literal">True</span>, port=<span class="hljs-number">8000</span>, host=<span class="hljs-string">'0.0.0.0'</span>)
</code></pre>
<p>This is a basic HTTP server that sends a "Hello, World!" JSON response when accessed at the root.</p>
<h4 id="heading-the-requirementstxt-file">The <code>requirements.txt</code> file</h4>
<hr />
<p>The <code>requirements.txt</code> file is crucial in Python projects, especially when it comes to containerization. It lists all the dependencies needed for a project, ensuring that the same environment can be replicated consistently across different systems. This is particularly important in containerization, as it allows Docker and other containerization tools to create isolated environments with all necessary packages pre-installed, facilitating seamless deployment and scalability.</p>
<p>Here's where the benefits of using a <code>.venv</code> come into play. Since we're utilizing <code>venv</code>, we don't need to list the dependencies individually. Instead, we can use:</p>
<pre><code class="lang-bash">pip freeze &gt; requirements.txt
</code></pre>
<p><code>pip freeze</code> retrieves all dependencies and their versions, conveniently listing them in a file. In our case, it would look something like this:</p>
<pre><code class="lang-plaintext">blinker==1.9.0
click==8.1.8
Flask==3.1.0
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.2
Werkzeug==3.1.3
</code></pre>
<p>Notice how the version numbers are also stored. This approach is always recommended.</p>
<h4 id="heading-to-the-good-stuff-dockerfile">To The Good Stuff : Dockerfile</h4>
<hr />
<p>A Dockerfile is a text document that contains a series of instructions for building a Docker image. It specifies the base image, dependencies, environment variables, and commands to set up a containerized application.</p>
<p>It serves as a blueprint for creating consistent and reproducible environments, ensuring that the application runs the same way across different systems.</p>
<pre><code class="lang-Dockerfile"><span class="hljs-comment"># Use the official Python 3.11 image based on Alpine Linux for a lightweight base image</span>
<span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.11</span>-alpine

<span class="hljs-comment"># Set the working directory inside the container</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

<span class="hljs-comment"># Copy all files from the current directory to the working directory in the container</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>

<span class="hljs-comment"># Install the required Python dependencies listed in requirements.txt without caching</span>
<span class="hljs-keyword">RUN</span><span class="bash"> pip install --no-cache-dir -r requirements.txt</span>

<span class="hljs-comment"># Specify the command to run the application</span>
<span class="hljs-keyword">CMD</span><span class="bash"> [ <span class="hljs-string">"python3"</span>, <span class="hljs-string">"main.py"</span> ]</span>
</code></pre>
<p><code>FROM</code> The <code>FROM</code> command is utilized to designate the base image for the container. There are numerous base images available, such as Alpine, python3:11, and others. We can select our base image based on our specific needs.</p>
<p><code>WORKDIR</code> The <code>workdir</code> command is utilized to designate the working directory. The <code>workdir</code> directive in a Dockerfile specifies the working directory for any subsequent instructions within the file. This sets the context for commands like <code>RUN</code>, <code>CMD</code>, and <code>ENTRYPOINT</code>, ensuring they execute within the designated directory.</p>
<p><code>COPY</code> The <code>COPY</code> command in Docker facilitates the transfer of files or directories from the host system to the Docker image during the build phase. This is crucial for incorporating essential files and dependencies required by the application running inside the container.</p>
<p><code>RUN</code> The <code>RUN</code> directive in a Dockerfile is used to execute commands within the context of the image's filesystem during the build process. It creates a new layer in the image for each command, allowing for efficient caching and layer reuse. This directive is essential for installing software, configuring settings, and preparing the environment for the application.</p>
<p><code>CMD</code> In a Dockerfile, the <code>CMD</code> instruction specifies the default command to run when a container starts. It can be overridden at runtime, but it provides a convenient way to define the container's primary operation.</p>
<h4 id="heading-docker-build-command"><code>docker build</code> Command</h4>
<hr />
<p>The <code>docker build</code> command is used to create a Docker image from a Dockerfile, which contains a set of instructions for building the image. This command reads the Dockerfile and executes each instruction to assemble the image layer by layer, resulting in a ready-to-use Docker image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347924902/874c184f-8a2d-41fd-b706-56c537f9a9bf.png" alt class="image--center mx-auto" /></p>
<p>When performing a <code>docker build</code> with the <code>-t</code> option, this option is used to name the image as <code>simple-http-server</code>. The path that follows must specify the location of the Dockerfile, with <code>.</code> indicating the current directory.</p>
<p>Now, we can execute <code>docker images</code> to view the available images.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347931774/ef6c1b40-3453-4111-9d5d-ba3c52b68822.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-running-the-application-with-a-docker-image">Running the Application with a Docker Image</h3>
<hr />
<p>Let's execute the application using the following command:</p>
<p><code>docker run -d --name sussy-baka -p 8000:8000 simple-http-server:latest</code></p>
<p><code>-d</code>: This flag runs the container in detached mode, meaning it will run in the background.</p>
<p><code>--name sussy-baka</code>: This option assigns the name <code>sussy-baka</code> to the container. This name can be used to reference the container in other Docker commands.</p>
<p><code>-p 8000:8000</code>: This flag maps port 8000 of the host machine to port 8000 of the container. This allows you to access the application running inside the container via port 8000 on your host machine.</p>
<p><code>simple-http-server:latest</code>: This specifies the image to use for the container. In this case, it is the <code>simple-http-server</code> image with the <code>latest</code> tag, which indicates the most recent version of the image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347941895/55b6399b-43f1-4a07-a78e-e045e51a4248.png" alt class="image--center mx-auto" /></p>
<p>A starting message will be displayed on the screen after executing the command <code>98c4b401a508d7e252186862016e4e26e2ac86a61d084123e194ecd35130363d</code>. This is the container ID of the running container.</p>
<p>We can use this to refer to the container if we need to stop, restart, or even remove it. Now, when we execute <code>docker ps</code>, we can observe the container in operation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347953222/966f11a3-28d5-4ebb-b0c3-79215dad57fd.png" alt class="image--center mx-auto" /></p>
<p>Let's utilize the <code>curl</code> command to verify that we are receiving a valid response.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347950575/afb6714f-9523-4a58-b91f-4069bf99b7e8.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Graph Theory Basics for Social Network Analysis]]></title><description><![CDATA[Introduction to Graphs
A graph is a mathematical structure that consists of nodes, also known as vertices, and edges, which connect pairs of nodes. These components represent relationships between objects, where nodes can symbolize entities and edges...]]></description><link>https://blogs.praful.dev/graph-theory-basics-for-social-network-analysis</link><guid isPermaLink="true">https://blogs.praful.dev/graph-theory-basics-for-social-network-analysis</guid><category><![CDATA[Math]]></category><category><![CDATA[social network]]></category><category><![CDATA[graph theory]]></category><dc:creator><![CDATA[Praful M]]></dc:creator><pubDate>Sat, 12 Jul 2025 19:11:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752348569044/1b42eebb-250d-4adb-9256-07422081f675.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction-to-graphs">Introduction to Graphs</h1>
<p>A graph is a mathematical structure that consists of nodes, also known as vertices, and edges, which connect pairs of nodes. These components represent relationships between objects, where nodes can symbolize entities and edges depict the connections or interactions between them. Graphs are fundamental in various fields, including computer science, network theory, and social sciences, for modeling and analyzing complex systems and relationships.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347028711/93485917-5cb6-47cc-9367-562eb7864fa7.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-types-of-graph">Types of Graph</h1>
<ol>
<li><p><strong>Empty Graph</strong>: A graph is considered an empty graph if it has no edges, meaning it consists solely of isolated vertices (nodes) with no connections between them.</p>
</li>
<li><p><strong>Trivial Graph</strong>: A graph consisting of just one node is referred to as a trivial graph.</p>
</li>
<li><p><strong>Simple Graph</strong>: A graph is considered simple if it contains no loops. These types of graphs are unique.</p>
</li>
<li><p><strong>Multigraph</strong>: These graphs include loops and may have multiple edges.</p>
</li>
</ol>
<h2 id="heading-line-set">Line Set</h2>
<p>A <strong>line set</strong> in graph theory refers to a <strong>collection of edges within a graph</strong>. This set can be used to represent various structures or properties of the graph, such as cycles, paths, or cuts. Linesets are essential for analyzing the connectivity and other topological features of graphs. They can also be used in algorithms that involve edge operations, such as finding minimum spanning trees or detecting cycles.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Node</td><td>Actor</td><td>Lives Near</td></tr>
</thead>
<tbody>
<tr>
<td>n₁</td><td>Allison</td><td>Ross, Sarah</td></tr>
<tr>
<td>n₂</td><td>Drew</td><td>Eliot</td></tr>
<tr>
<td>n₃</td><td>Eliot</td><td>Drew</td></tr>
<tr>
<td>n₄</td><td>Keith</td><td>Ross, Sarah</td></tr>
<tr>
<td>n₅</td><td>Ross</td><td>Allison, Keith, Sarah</td></tr>
<tr>
<td>n₆</td><td>Sarah</td><td>Allison, Keith, Ross</td></tr>
</tbody>
</table>
</div><h3 id="heading-lines">Lines</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Lines</td><td>Connection</td></tr>
</thead>
<tbody>
<tr>
<td>l₁</td><td>(n₁, n₅)</td></tr>
<tr>
<td>l₂</td><td>(n₁, n₆)</td></tr>
<tr>
<td>l₃</td><td>(n₂, n₃)</td></tr>
<tr>
<td>l₄</td><td>(n₄, n₅)</td></tr>
<tr>
<td>l₅</td><td>(n₄, n₆)</td></tr>
<tr>
<td>l₆</td><td>(n₅, n₆)</td></tr>
<tr>
<td>For instance, consider the following line set (set of edges): l2(n1,n6), $l_6(n_5, n_6)$, $l_1(n_1, n_5)$. This represents a sub graph within the main graph that is also complete. This serves as an example of a line set.</td></tr>
</tbody>
</table>
</div><p>In some contexts, a lineset might specifically denote the set of all edges in a graph, but it can also refer to a subset of edges that satisfy certain conditions or criteria relevant to a particular problem or analysis.</p>
<h1 id="heading-sub-graphs-graph-within-a-graph">Sub-graphs : Graph Within A Graph ??</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347040636/21d1b661-9539-46dd-be06-acc7ccf84a33.png" alt class="image--center mx-auto" /></p>
<p>A subgraph is a smaller graph that is derived from a larger graph by selecting a subset of its vertices and edges. It retains the structure and relationships of the chosen elements within the original graph, allowing for focused analysis or manipulation of specific parts of the data. Subgraphs are useful for examining particular aspects of a network without the complexity of the entire structure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347054906/241a95d0-999b-413e-bb78-d2b181bfffe8.png" alt class="image--center mx-auto" /></p>
<p>Here, in the image above, we observe the original graph in (a). We then remove the top-left node from the graph. Since we've deleted a node, we must also remove the edges connected to it, as edges are associated with two nodes, which can be the same or different. Therefore, by deleting a node, we must also delete its edges, resulting in the graph shown in (c).</p>
<h2 id="heading-dyads">Dyads</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347082585/d1de0e79-1f38-40a7-a0e7-bc4b6c773fd1.png" alt class="image--center mx-auto" /></p>
<p>In graph theory, a dyad refers to a pair of vertices that are connected by an edge. Dyads are fundamental units in the study of graph structures and their properties.</p>
<p>In sociology, a dyad serves as a foundational element, representing the smallest possible social network. The term "dyad" originates from the Ancient Greek word <a target="_blank" href="https://en.wiktionary.org/wiki/%CE%B4%CF%85%CE%AC%CF%82#Ancient_Greek">δυάς</a> (<em>duás</em>), meaning 'pair'.</p>
<h2 id="heading-triads">Triads</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347097263/a11fc837-1389-4bfb-9d4a-d1b71ee85fe1.png" alt class="image--center mx-auto" /></p>
<p>A <strong>triad</strong> in graph theory generally refers to three nodes <strong>with at least two edges among them</strong>—either forming an <strong>open triad</strong> (like A–B and B–C but A–C missing) or a <strong>closed triad</strong> (a triangle).</p>
<p>he study of triads is crucial for understanding the local structure of a graph. Triads can be classified based on the presence or absence of edges between the vertices, such as <strong>open triads</strong> (one edge) and <strong>closed triads</strong> (three edges forming a triangle). Analyzing triads helps in identifying patterns and properties within complex networks.</p>
<h3 id="heading-open-triads">Open Triads</h3>
<p>Open triads consist of three individuals where only two pairs are directly connected. This structure allows for potential new connections to form.</p>
<p>In an open triad, individuals A and B are friends, as are B and C, but A and C are not yet connected. An example of this is when you have a friend who introduces you to another friend, creating a connection between you, your friend, and their friend. This is what we refer to as an open triad.</p>
<h3 id="heading-closed-triads">Closed Triads</h3>
<p>Closed triads involve three individuals where all pairs are directly connected, forming a complete network of relationships.</p>
<p>This configuration features robust, mutual connections between all three individuals. For instance, consider a trio of close friends; each member shares a strong bond with the others, resulting in a closed triad.</p>
<h3 id="heading-open-triad-to-closed-triad-transition-in-social-networks">Open Triad to Closed Triad Transition in Social Networks</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347109586/c00ec833-3919-46a1-95d7-48a3494885f4.png" alt class="image--center mx-auto" /></p>
<p>In sociology, the concept of triad closure refers to the process where an open triad transitions into a closed triad. This occurs when individuals A and C, who were not previously connected, form a friendship due to the existing friendship between A and B, and B and C. This new connection between A and C completes the triad, transforming it into a closed structure with mutual ties among all three individuals.</p>
<h2 id="heading-nodal-degrees">Nodal Degrees</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347119151/f1e118ae-5e14-4dae-8013-032abff3ac0c.png" alt class="image--center mx-auto" /></p>
<p>In network analysis, nodal degrees refer to the number of connections or edges emanating from a specific node. This metric is crucial for understanding a node's centrality and influence within the network. Higher nodal degrees often indicate more significant roles or greater connectivity for the node in question.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347126068/4e566b5c-85f3-476b-858b-92cc4a32916b.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><strong>Allison</strong>: Nodal degree of 2</p>
</li>
<li><p><strong>Drew</strong>: Nodal degree of 1</p>
</li>
<li><p><strong>Eliot</strong>: Nodal degree of 1</p>
</li>
<li><p><strong>Keith</strong>: Nodal degree of 2</p>
</li>
<li><p><strong>Ross</strong>: Nodal degree of 3</p>
</li>
<li><p><strong>Sarah</strong>: Nodal degree of 3</p>
</li>
</ul>
<h2 id="heading-types-of-graph-1">Types of Graph</h2>
<p><strong>Connected Graph</strong> A connected graph is one where you can navigate from any node to any other node. For instance, in a social network, consider a group of friends where everyone knows each other directly or through mutual friends. If you can send a message from any person to any other person in the group, either directly or through intermediaries, the social network forms a connected graph.</p>
<p><strong>Complete Graph</strong> A complete graph is one where every node is connected to every other node, meaning all nodes have the same degree. In a social network context, imagine a small team where each member is directly connected to every other member. If everyone in the team follows each other on a social media platform, this forms a complete graph, as each node (team member) has the same number of connections (follows every other member).</p>
<p><strong>Disconnected Graph</strong> A disconnected graph is one where there are nodes or groups of nodes that cannot be reached from certain other nodes. In a social network, consider two separate friend groups that do not know each other. If there is no mutual friend or connection between the two groups, the social network is a disconnected graph. For example, if Group A and Group B have no common members or indirect connections, they form separate components within the graph, making it disconnected.</p>
<h1 id="heading-geodesic-distance">Geodesic Distance</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347138016/949a7d5b-f13a-41a3-8e33-21858bf1c16f.png" alt class="image--center mx-auto" /></p>
<p>A <strong>geodesic</strong> is a term that refers to the shortest path between two points on a curved surface. The word itself comes from the Greek words "geo," meaning "earth," and "daiein," meaning "to divide." In essence, a geodesic is the most direct route on a given surface, such as the surface of a sphere or any other curved space.</p>
<p>The geodesic distance is always defined between a pair of vertices. Therefore, the next time you want to ask for directions from Bengaluru to Chennai, you should ask:</p>
<p>"Hello, kind person. May I know the geodesic distance between Bengaluru and Chennai, assuming all roads are modelled as edges and major cities are modeled vertices as graphs?"</p>
<p>Given this, how do you think it will be applicable in the context of graph theory and social networks?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347156991/fc81fd62-ca9a-4491-94c6-34130abf6bb9.png" alt class="image--center mx-auto" /></p>
<p>In this graph, the geodesic distance between <code>n1</code> and <code>n2</code> is 1, as it only requires traversing 1 edge. Now, consider the path from <code>n1</code> to <code>n3</code>. There is a route through <code>n1 -&gt; n2 -&gt; n3</code>, but the geodesic distance does not account for this because it is not the shortest. The shortest distance is actually <code>n1 -&gt; n3</code> via the direct edge.</p>
<h1 id="heading-bipartite-graph">Bipartite Graph</h1>
<p>A bipartite graph is a type of graph whose vertices can be divided into two disjoint sets such that no two graph vertices within the same set are adjacent. This structure ensures that every edge connects a vertex in one set to a vertex in the other set, making it useful in various applications like matching problems and network design.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347161603/4b2652df-9a4f-4db9-be87-0e77d12741fa.png" alt class="image--center mx-auto" /></p>
<p>In a bipartite graph, the absence of edges within the same set simplifies certain algorithms and analyses, providing a clear separation of vertices into two distinct groups.</p>
<p>A bipartite graph is also known as a two-colorable graph, which means it can be colored using just two colors in such a way that no two adjacent vertices share the same color.</p>
<h2 id="heading-complete-bipartite-graph">Complete Bipartite Graph</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347177915/f9aaaf97-0077-4ee9-93ea-cfaf8a4cd37e.png" alt class="image--center mx-auto" /></p>
<p>A complete bipartite graph is a special type of bipartite graph where every vertex in one set is connected to every vertex in the other set. This structure ensures that there are no edges between vertices within the same set, and every possible edge between the two sets is present. It is denoted as K_{m,n}, where m and n represent the number of vertices in each set.</p>
<h1 id="heading-eccentricity-of-a-node-in-a-graph">Eccentricity of a Node in a Graph</h1>
<h2 id="heading-meaning-of-eccentricity">Meaning of Eccentricity</h2>
<p>The term "eccentricity" in graph theory refers to the maximum distance between a vertex and any other vertex in the graph, and it is named so because it measures how "off-center" or distant a vertex is from others.</p>
<h2 id="heading-formal-definition">Formal Definition</h2>
<p>For a vertex v in a graph G, the <strong>eccentricity</strong> e(v) is defined as:</p>
<p>$$e(v) = \max(d(v, u))$$</p><p>where $d(v, u)$ is the shortest path distance between $v$ and any other vertex $u$ in the graph.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752347185847/0eba0844-da52-46c0-9fc2-14d253b69c39.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-eccentricity-calculation">Eccentricity Calculation</h2>
<p>The eccentricity of a node ( v ) is determined by finding the distance from ( v ) to every other node ( u ) in the graph. These distances are stored in an array, and the maximum value in this array is identified as the eccentricity.</p>
<p>Here is a basic Python code snippet to illustrate this process</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculate_eccentricity</span>(<span class="hljs-params">graph, node</span>):</span>
    <span class="hljs-string">"""
    Calculate the eccentricity of a given node in a graph.

    Parameters:
    graph (dict): A dictionary representing the graph. Keys are nodes, and values are lists of neighboring nodes.
    node (any): The node for which to calculate the eccentricity.

    Returns:
    int: The eccentricity of the node.
    """</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">distance</span>(<span class="hljs-params">source, dest</span>):</span>
        <span class="hljs-string">"""
        Abstracted distance function to calculate the distance between two nodes.

        Parameters:
        source (any): The source node.
        dest (any): The destination node.

        Returns:
        int: The distance between the source and destination nodes.
        """</span>
        <span class="hljs-comment"># Implement the distance calculation here</span>
        <span class="hljs-keyword">pass</span>

    max_distance = <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> dest <span class="hljs-keyword">in</span> graph:
        <span class="hljs-keyword">if</span> dest != node:
            dist = distance(node, dest)
            <span class="hljs-keyword">if</span> dist &gt; max_distance:
                max_distance = dist
    <span class="hljs-keyword">return</span> max_distance
</code></pre>
<h1 id="heading-radius-of-a-graph">Radius of a Graph</h1>
<p>The radius of a graph is the minimum eccentricity among all vertices within the graph. It represents the smallest distance from any vertex to the farthest vertex, providing a measure of the graph's overall connectivity and compactness.</p>
<p>$$r(G) = \min_{\{v \in V\}} \max_{\{u \in V\}} d(u, v)$$</p><p>where V is the set of vertices and d(u, v) is the distance between vertices u and v.</p>
<p>Imagine you’re designing a <strong>data center network</strong> where you have multiple servers connected in a complex way. The radius of the network graph helps you <strong>identify the most central server</strong>—the one that can reach all other servers the quickest (in terms of network hops).</p>
<ul>
<li><p>You can place <strong>caching servers</strong> at these central nodes to reduce latency.</p>
</li>
<li><p>Helps in <strong>load balancing</strong>—requests can be directed to the most "efficient" server.</p>
</li>
</ul>
<h1 id="heading-diameter-of-a-graph">Diameter of a Graph</h1>
<p>For a graph G, the <strong>diameter</strong> D(G) is defined as:</p>
<p>$$D(G) = \max_{v \in V} \max_{u \in V} d(u, v)$$</p><p>where e(v) represents the <strong>eccentricity</strong> of vertex v, which is the greatest shortest path distance from v to any other vertex.</p>
]]></content:encoded></item></channel></rss>