<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Paul DiGian</title>
    <description>The latest articles on DEV Community by Paul DiGian (@digianpaul).</description>
    <link>https://dev.to/digianpaul</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F376387%2F8e78158f-2d30-45af-953b-1962d3341897.jpg</url>
      <title>DEV Community: Paul DiGian</title>
      <link>https://dev.to/digianpaul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/digianpaul"/>
    <language>en</language>
    <item>
      <title>Linux Processes</title>
      <dc:creator>Paul DiGian</dc:creator>
      <pubDate>Tue, 11 Aug 2020 15:17:43 +0000</pubDate>
      <link>https://dev.to/digianpaul/linux-processes-5bmf</link>
      <guid>https://dev.to/digianpaul/linux-processes-5bmf</guid>
      <description>&lt;p&gt;Understanding the concept of processes is fundamental when working with computers.&lt;/p&gt;

&lt;p&gt;Most articles tackle the issue from a quite shallow perspective or the wrong point of view. We will try to study them from what I believe is the most useful point of view for a senior computer engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What processes are
&lt;/h2&gt;

&lt;p&gt;Processes are a computational unit.&lt;/p&gt;

&lt;p&gt;This definition is neither precise nor completely correct, but it helps in understanding.&lt;/p&gt;

&lt;p&gt;Whenever you run a program a new process is created. Each software that you are running now in your machine is a process.&lt;/p&gt;

&lt;p&gt;Your browser? It is (at least one) process. Your mail client? Another one. Your bash terminal? Yet another process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolation
&lt;/h2&gt;

&lt;p&gt;The most important concept to understand about a process is "isolation". Processes are isolated one from another. One process cannot read nor write memory that belongs to another process. Actually, it is even more strict. One process can write and read, only the memory that belongs to itself.&lt;/p&gt;

&lt;p&gt;The difference is that a process cannot access memory that belongs to no-one. It can access only its own memory.&lt;/p&gt;

&lt;p&gt;If the isolation is not respected and a process tries to read or write (access from now on) memory that does not belong to itself, the process is forcefully terminated by the operative system with a &lt;strong&gt;segmentation fault&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All the time a segmentation fault is thrown, it means that the process did not behave correctly and it was trying to access memory that didn’t belong to it.&lt;/p&gt;

&lt;p&gt;Isolation is the greatest advantage of processes. It assures that the content of the memory never changes under your feet and that you are the only one to have access to the memory.&lt;/p&gt;

&lt;p&gt;While this advantage doesn’t seem particularly interesting, and maybe also bland, modern (complex) software takes full advantage of it.&lt;/p&gt;

&lt;p&gt;For instance, Redis (a NoSQL database) use a single execution unit to avoid coordination keeping the software extremely fast. The alternative would have been to use thread, hence more execution units, and to introduce locks and a great deal of complexity in managing multiple execution units changing a shared memory.&lt;/p&gt;

&lt;p&gt;Modern browsers, have one process for each tab. This avoids malicious code to gain access to data in other tabs. The use of multiple processes, one for each tab, makes it impossible that javascript code running in a tab from a pishing website, can access any data from a tab from your bank.&lt;/p&gt;

&lt;p&gt;Isolation is a wonderful capability, but it comes at a cost. Software, to be useful, need to read input and produce output. So a process needs some way to get input from the outside world and to push its output.&lt;/p&gt;

&lt;p&gt;Introducing IPC or Inter Process Communication&lt;/p&gt;

&lt;h2&gt;
  
  
  Inter Process Communication
&lt;/h2&gt;

&lt;p&gt;We discussed how processes are isolated, we agree that isolation is a great capability for processes, but that it comes at a cost. It makes difficult input/output. We are now introducing how processes can communicate with each other and with the outside world.&lt;/p&gt;

&lt;p&gt;We will have a different section for each of the IPC methods we are describing, so the discussion on this page will be rather short.&lt;/p&gt;

&lt;p&gt;For maintaining isolation is important that it is always the process to drive the I/O. It can not happen that some data change without the process having asked it explicitly. This is in stark contrast to what happens with threads.&lt;/p&gt;

&lt;p&gt;Using threads it is possible that some value changes without one thread explicit permission. So a thread could read a variable, do some other work without ever writing anything to that variable, and then find the initial variable changed. Another thread, in the same process, changed that variable. This is a source of many, very complex to reproduce and to address bugs. And this does not happen between processes. Of course, there is an exception to this general rule.&lt;/p&gt;

&lt;p&gt;We will now explore the most common IPC methods, starting from the most useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sockets
&lt;/h3&gt;

&lt;p&gt;Sockets are extremely important IPC methods. They allow communication between processes that reside on different machines or on the same computer. For instance, you used a socket to download this article from the web and read it.&lt;/p&gt;

&lt;p&gt;The interface for sockets is relatively simple. You start by establishing a connection and then you can read data from the socket or write data into it.&lt;/p&gt;

&lt;p&gt;More practically, when you establish a connection with a socket, the operative systems give you back an handle for the connection the handle is called file descriptor. (We will study why it is called a file descriptor, so subscribe to the mail list or follow me on twitter.) After you get the handle, you create a buffer of memory.&lt;/p&gt;

&lt;p&gt;To read from a socket, you pass the socket handle and the buffer to the operative system using the read system call. The operative system will first interrupt your process, then it will fill the buffer with data, and then it will resume the execution of your code. Now the buffer contains the data read from the socket and you can act on it.&lt;/p&gt;

&lt;p&gt;To write to a socket, you do the inverse operation. You fill your buffer with data. You pass the socket handle and the buffer to the write system call. The operative system interrupts your process, reads the data from the buffer, moves the data to the other end of the socket, and finally resume the execution of your code.&lt;/p&gt;

&lt;p&gt;There is much more to study about sockets and I will write about them shortly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signal
&lt;/h3&gt;

&lt;p&gt;A less versatile way for processes to get information from the outside world is signal.&lt;/p&gt;

&lt;p&gt;Signals are short messages sent to a process, each signal has associated a default action. The default actions are to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Terminate the process&lt;/li&gt;
&lt;li&gt;Ignore the signal&lt;/li&gt;
&lt;li&gt;Terminate the process and write possible debug information (dump the core).&lt;/li&gt;
&lt;li&gt;Stop (temporarily) the process&lt;/li&gt;
&lt;li&gt;Resume the execution of a process stopped earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A signal can be sent from one process to another and can be caught from the process and acted upon.&lt;/p&gt;

&lt;p&gt;For instance, several systems catch &lt;code&gt;SIGHUP&lt;/code&gt; to reload their configurations. Other systems catch &lt;code&gt;SIGTERM&lt;/code&gt; (&lt;code&gt;Ctrl-C&lt;/code&gt;) to terminate cleanly the execution and not lose data or important information.&lt;/p&gt;

&lt;p&gt;Some signal (&lt;code&gt;SIGKILL&lt;/code&gt; and &lt;code&gt;SIGSTOP&lt;/code&gt;) cannot be caught, nor ignored, and they just kill the process without giving it the possibility to exit cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Files
&lt;/h3&gt;

&lt;p&gt;Files are another great way to communicate between processes. One process can write in a file, and another could read from it.&lt;/p&gt;

&lt;p&gt;The interface to work with files is exactly the same to work with sockets. You acquire a file descriptor first, then you create a buffer, and finally, invoke the read or write system calls. This similarly would give a hit on why the socket handles are called file descriptor. Underneath they are the same.&lt;/p&gt;

&lt;p&gt;Using files for IPC allows processes to communicate between the same machine, they both need to have access to the same file.&lt;/p&gt;

&lt;p&gt;Files come also with another complication, there must be coordination between write and read operations. Locks and semaphores are used in these cases.&lt;/p&gt;

&lt;p&gt;A great way to use files are IPC is to use tools like SQLite. SQLite can write and read directly from a file and it takes care of all the coordination for you. An application can write data to an SQLite database, while a second one consumes data from it. This approach works great even if it is difficult to receive notifications of writes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared Mapped Memory
&lt;/h3&gt;

&lt;p&gt;The final and most complex way to IPC is mapped memory. This method is not that different from using files but does not rely on an explicit read and write calls. It is quite dangerous because allow data, in the share mapped memory, to be changed implicitly by another process. The data that you read from it, now and in the future, maybe different even if you never changed it.&lt;/p&gt;

&lt;p&gt;You can create a shared mapped memory invoking the mmap system call passing the appropriate flags. Other processes can do the same. At this point, processes have access to a memory buffer that is shared between them. What a process writes in the buffer can be read by the others.&lt;/p&gt;

&lt;p&gt;Notice how this is the only method that allows implicit changes to the memory owned by the process. With all the other methods you provide a buffer that it is changed when you ask so, using the read system call. With this method, the values stored in the shared memory can change under your feet.&lt;/p&gt;

&lt;p&gt;There are more IPC methods but the one provided is an interesting overview, much more than enough to get started.&lt;/p&gt;

&lt;p&gt;We continue this chapter on how to work effectively with processes in a Linux system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start a process
&lt;/h2&gt;

&lt;p&gt;There are few ways in Linux to create another process. The most used one is the &lt;code&gt;fork&lt;/code&gt; system call. It creates a copy of the actual process and starts to run it while the original process keeps running. The &lt;code&gt;fork&lt;/code&gt; system call returns a different result on the "parent"/"original" process (it returns 0 zero) from the "child" process (it returns an ID greater than zero). Detecting the return value of the &lt;code&gt;fork&lt;/code&gt; call is possible to distinguish between the child and the parent process.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;clone&lt;/code&gt; system call is similar but allows for more control. It is a more advanced function and it is used in the implementation of container technologies. It also returns the ID of the new process.&lt;/p&gt;

&lt;p&gt;Another related function is &lt;code&gt;execve&lt;/code&gt; it does not create a new process, but it executes a new program in place of the original one. It is not strictly related to this topic, but, together with &lt;code&gt;fork&lt;/code&gt; is enough to implement a simple shell (like &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;sh&lt;/code&gt; or &lt;code&gt;fish&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Process identification
&lt;/h2&gt;

&lt;p&gt;We saw how to start a process with the &lt;code&gt;fork&lt;/code&gt; system call, and we see that &lt;code&gt;fork&lt;/code&gt; returns an ID. Since the ID identifies a &lt;strong&gt;P&lt;/strong&gt;rocess, those IDs are called PID, for Process ID.&lt;/p&gt;

&lt;p&gt;The number of PID is limited, they are stored in an &lt;code&gt;int&lt;/code&gt;, so in systems running for a long time with a lot of processes starting up, the PID will get recycled. However, at any given time, a PID identifies one and only one process.&lt;/p&gt;

&lt;p&gt;Knowing the PID of a process is possible to interact with it. Sending it signals or attach it to a debugger.&lt;/p&gt;

&lt;p&gt;The simplest way of knowing the PID of a process is to store it when you create it. Of course, it is not always possible since you may need to know the PID of a process not created by you.&lt;/p&gt;

&lt;p&gt;Fortunately, there are other ways to know the PID of the processes running in the system at any given moment.&lt;/p&gt;

&lt;p&gt;All those methods rely on reading data from &lt;code&gt;/proc&lt;/code&gt;. Inside &lt;code&gt;/proc&lt;/code&gt; there are several directories, one for each &lt;code&gt;PID&lt;/code&gt;, in the form &lt;code&gt;/proc/[PID]&lt;/code&gt;, listing them is a simple way to know which processes are running in the system at any given moment. To list the process we can rely on bash globing with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls -lna /proc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will show a lot of directories. The numeric ones are the PID, while the others are for system information.&lt;/p&gt;

&lt;p&gt;Inside those directories, there are a lot of files with very interesting information.&lt;/p&gt;

&lt;p&gt;For instance &lt;code&gt;/proc/[pid]/cmdline&lt;/code&gt; contains how the software was invoked. &lt;code&gt;/proc/[pid]/exe&lt;/code&gt; is a symbolic link to the executable that is running and &lt;code&gt;/proc/[pid]/comm&lt;/code&gt; contains the name of the software.&lt;/p&gt;

&lt;p&gt;Fortunately, we don’t have to rely on manually parsing the content of the &lt;code&gt;/proc&lt;/code&gt; directories since different utilities are available for us.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ps&lt;/code&gt; utility allows to list all the processes running in the system, it is useful to identify the PID of a specific software running in the system. I am writing this article on &lt;code&gt;nvim&lt;/code&gt; so if I want to know the PID of &lt;code&gt;nvim&lt;/code&gt; I could run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ps -e | grep nvim
27188 pts/1    00:01:08 nvim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And this will show me that the PID of this instance of &lt;code&gt;nvim&lt;/code&gt; is &lt;code&gt;27188&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another way to use &lt;code&gt;ps&lt;/code&gt; is to pass the &lt;code&gt;aux&lt;/code&gt; options, this will show more information. Information like the arguments that were passed to the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ps aux | grep nvim
pgian 27188  3.4  0.1 129616 13764 pts/1    Sl+  17:49   1:29 nvim content/posts/process.asciidoc
pgian 27518  0.0  0.0  14752  1028 pts/2    S+   18:32   0:00 grep --color=auto nvim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can see the user, the PID, and the command-line invocation of the software. Notice how this shows also grep indeed, grep is matching its own invocations.&lt;/p&gt;

&lt;p&gt;While &lt;code&gt;ps&lt;/code&gt; is great for quickly get to know the PID of a process, it is not very ergonomic when exploring a running system. A better alternative in such cases is &lt;code&gt;htop&lt;/code&gt;. &lt;code&gt;htop&lt;/code&gt; allow also to sort the processes in a system to visually show the processes tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---MnEHp28--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9tojvb3vxbcnrivkbul3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---MnEHp28--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9tojvb3vxbcnrivkbul3.png" alt="htop view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can my setup as I am writing the article. I am running the software inside &lt;code&gt;tmux&lt;/code&gt; (PID 27177), which in turn, runs 3 bash command lines (27731, 27217 and 27178). In turn, one bash shell runs &lt;code&gt;nvim&lt;/code&gt; again with PID 27188 and another is running &lt;code&gt;htop&lt;/code&gt; (27681).&lt;/p&gt;

&lt;p&gt;We started talking about processes, we talk about isolation and why isolation is fundamental, we discover that isolation is great, but we need to do input and output. Then we study some Inter Process Communication (IPC) mechanism. In this last part, we studied how it is possible to see all the processes running in the system with tools like &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;htop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this last part, we will understand the state of a process. At the very beginning, we describe processes as a computational unit. Modern computers can run a lot of processes at the same time, while I am writing this, I have 285 processes running. However the number of virtual cores in a computer is limited, my machine has only 4. So how 4 cores can run 285 processes?&lt;/p&gt;

&lt;p&gt;Of course, not all processes run at the same time. Some of them sleep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process State
&lt;/h2&gt;

&lt;p&gt;It is not necessary for software to keep running continuously. If you are reading or writing from a file descriptor your CPU does not need to work. The CPU is waiting for the IO layer to finish, either against the disk or against the network. In this case, the process is sleeping.&lt;/p&gt;

&lt;p&gt;On the contrary, when the CPU is working, for instance, it is summing numbers, creating strings, doing some math operations, moving memory, the process is running.&lt;/p&gt;

&lt;p&gt;Besides the &lt;code&gt;sleeping&lt;/code&gt; and the &lt;code&gt;running&lt;/code&gt; state of a process, there is a third state, the &lt;code&gt;ready&lt;/code&gt; state. A process is in the &lt;code&gt;ready&lt;/code&gt; state when it has done waiting, for instance, the disk finally finished returned some data, but it is not yet running, because the operative system has not allocated yet resources to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;In this chapter, we study processes. We understand what they are and one of their most important features, isolation.&lt;/p&gt;

&lt;p&gt;Isolation is great, but software needs to communicate with the outside world, hence several Inter Process Communication (IPC) mechanisms are available. We study briefly, sockets, signals, files, and shared mapped memory.&lt;/p&gt;

&lt;p&gt;Then we study how to start a process and how to identify processes in a running machine. We interact with the raw tools that the operative system gives us to query processes and then we upgraded to work with more refined tools like &lt;code&gt;ps&lt;/code&gt; and &lt;code&gt;htop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we understood what is the state of a process and what are the main states a process can be in, &lt;code&gt;sleeping&lt;/code&gt;, &lt;code&gt;running&lt;/code&gt; or &lt;code&gt;ready&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you enjoyed this post, make sure to check out the project &lt;a href="https://jr2sr.com"&gt;jr2sr.com&lt;/a&gt; to help you transition in a more senior engineering position.&lt;/p&gt;

&lt;p&gt;Also feel free to follow me on twitter: &lt;a href="https://twitter.com/pauldigian"&gt;@PauldiGian&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>jr2sr</category>
    </item>
    <item>
      <title>Practical DNS</title>
      <dc:creator>Paul DiGian</dc:creator>
      <pubDate>Thu, 11 Jun 2020 15:47:00 +0000</pubDate>
      <link>https://dev.to/digianpaul/practical-dns-14ki</link>
      <guid>https://dev.to/digianpaul/practical-dns-14ki</guid>
      <description>&lt;h1&gt;
  
  
  DNS
&lt;/h1&gt;

&lt;p&gt;DNS is part of Junior2Senior a course to help you grow as software engineers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jr2sr.com/posts/whats-a-web-request"&gt;In the first article, we describe what is a web/HTTP request.&lt;/a&gt; Requests are directed toward a host and a port.&lt;/p&gt;

&lt;p&gt;The port is defined by the protocol, HTTP goes to port 80, HTTPS goes to 443. The host is defined by the request as a string.&lt;/p&gt;

&lt;p&gt;A possible host is “google.com” another is “facebook.com”.&lt;/p&gt;

&lt;p&gt;However, packets are routed over the internet using IP addresses, numbers, while hosts are strings.&lt;/p&gt;

&lt;p&gt;Each IP packet must contain its source and its destination to be delivered. And the host of the source address and of the destination address must be encoded as IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--khnva4Il--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AVVMPY5OXLf4jGRMM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--khnva4Il--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AVVMPY5OXLf4jGRMM.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to create the IP packet and to deliver it to the internet, we need to convert the host name “kitty.com” in its IP address 53.125.12.9.&lt;/p&gt;

&lt;p&gt;DNS serves have the basic goal of translating the string that represents the host (“google.com”) in a number, the IP address ( 116.98.109.34) so that a valid IP packet can be generated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scratching the surface
&lt;/h2&gt;

&lt;p&gt;At its most basic level, DNS are services that take as input a host string and return the IP address of the host.&lt;/p&gt;

&lt;p&gt;A simple utility to test DNS is dig. In its most basic invocation, dig takes an input an host and returns its IPv4.&lt;/p&gt;

&lt;p&gt;The following examples have different options to provide a more concise output.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dig +noall +answer -t A google.com google.com. 275    IN  A   216.58.205.46 
$ dig +noall +answer -t AAAA google.com google.com. 257 IN  AAAA    2a00:1450:4009:81b::200e
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the first line we translate the host “google.com” into an IPv4 address ( 216.58.205.46).&lt;/p&gt;

&lt;p&gt;In the second line, for the same host, we retrieve its IPv6 ( 2a00:1450:4009:81b::200e).&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS record type
&lt;/h2&gt;

&lt;p&gt;DNS can store different kinds of records beside IP addresses. The most common record type is A that stores IPv4 addresses. The AAAA record stores IPv6 addresses.&lt;/p&gt;

&lt;p&gt;Another important record type is the CNAME (or ALIAS) record type. It is useful if a single machine, with only one IP address, runs multiple services on different ports.&lt;/p&gt;

&lt;p&gt;The TXT record type can contain arbitrary information, it is usually used to verify the ownership of a domain name.&lt;/p&gt;

&lt;p&gt;Other record types are available and widely used, but the working principle is the same for all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolve DNS query
&lt;/h2&gt;

&lt;p&gt;DNS works like any other internet service, but with some peculiarity.&lt;/p&gt;

&lt;p&gt;First of all, the IP address of the DNSs are widely know, for instance, the one provided by google is 8.8.8.8 and the one by Cloudflare is 1.1.1.1.&lt;/p&gt;

&lt;p&gt;Then DNS works mostly over UDP and not over TCP. The use of UDP is mostly for performance.&lt;/p&gt;

&lt;p&gt;Performance is the most strict requirement for DNS.&lt;/p&gt;

&lt;p&gt;DNS must be fast.&lt;/p&gt;

&lt;p&gt;In order to keep communication as concise and fast as possible, almost all packets DNS queries and responses fit into a single UDP packet and are limited to 512 bytes. If the DNS answer is bigger other communications protocols are used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need for speed
&lt;/h2&gt;

&lt;p&gt;The use of UDP over TCP is mostly due to performance requirements. Any application needs to make multiple DNS queries, it must be fast.&lt;/p&gt;

&lt;p&gt;Even if fast, it is still impractical to make a DNS query for each network request. Moreover, when visiting a website, most requests are against the same host in a short amount of time.&lt;/p&gt;

&lt;p&gt;To address the problem DNS is aggressively cached on different layers.&lt;/p&gt;

&lt;p&gt;Cached values eventually goes stale and they must be updated. For this reason, DNS records provide also a TTL value, Time To Live.&lt;/p&gt;

&lt;p&gt;After the TTL expires, the DNS value is considered outdated and it must be requested again from the authoritative domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server cache
&lt;/h2&gt;

&lt;p&gt;The first level of DNS cache is the server level. DNS servers don’t store all the values of all the domains, but only a small subset.&lt;/p&gt;

&lt;p&gt;If a request for an unknown domain comes, they recursively redirect the request to other DNS until they don’t get the answer from the authoritative (main) DNS. The answer is then cached until the TTL expires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client cache
&lt;/h2&gt;

&lt;p&gt;While server cached helps a lot in reducing the latency of DNS queries, it cannot be as fast as a local copy.&lt;/p&gt;

&lt;p&gt;Hence the first level of cache regarding the name server happens in the local machine.&lt;/p&gt;

&lt;p&gt;The OS intercepts DNS requests and returns a cached answer, as long as the TTL is not expired. As soon as the TTL expires a new request to the server is made and the answer cached again.&lt;/p&gt;

&lt;h2&gt;
  
  
  TTL and propagation time
&lt;/h2&gt;

&lt;p&gt;Caching the result of DNS queries has the huge benefits of making it fast. The downside is that updates to DNS take time.&lt;/p&gt;

&lt;p&gt;All the TTL needs to expire before all the users can see the updated values.&lt;/p&gt;

&lt;p&gt;It can take up to 2 days for the information to propagate in the DNS servers. For most applications, the delay is much smaller, a few hours at the very maximum in my experience using AWS Route53 or Cloudfront.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trivial
&lt;/h3&gt;

&lt;p&gt;DNS can store arbitrary information, and eventually all the DNS servers will agree on a specific values. For these reasons DNS are considered the biggest and more widely deployed eventual consistent databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS console
&lt;/h2&gt;

&lt;p&gt;After you buy a domain name you can set all the DNS values relative to that domain and all its subdomains.&lt;/p&gt;

&lt;p&gt;All the DNS interfaces are similar, offering pretty much the same functionality.&lt;/p&gt;

&lt;p&gt;Your DNS provider is mostly a matter of taste and convenience.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Route53
&lt;/h2&gt;

&lt;p&gt;I like to use Amazon Route53 service, that allows buying the domain and set the records in the same interface.&lt;/p&gt;

&lt;p&gt;I like Amazon Route53 because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;DNS is a fundamental service for AWS, it will always work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They provide very clear, simple, and cheap pricing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I trust Amazon don’t screw people over a few dollars in the domain registration fee, unlike other vendors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A domain on AWS cost ~12$ / year plus few cents if your domain is extremely popular or if you need special features.&lt;/p&gt;

&lt;p&gt;Beware that other vendors sell your domain at a much higher price BUT they provide a hefty discount for the first year. So it seems like you are buying it for 4$ and the second year they start charging you 50$ / year.&lt;/p&gt;

&lt;p&gt;In my opinion, it is just not worth doing business with them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trivial
&lt;/h3&gt;

&lt;p&gt;The DNS service of Amazon is called Route53, while Route is quite clear, why not Route 66, much more iconic. Or Route 101? Because 53 is the port used by the DNS protocol.&lt;/p&gt;

&lt;h3&gt;
  
  
  The console
&lt;/h3&gt;

&lt;p&gt;The console of AWS Route53 looks like this, for each of your domains.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vpw7hIq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2824/0%2ARlsMBO0HegJmpMHt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vpw7hIq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2824/0%2ARlsMBO0HegJmpMHt.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will focus on the big table. The navigation on the right is for more (advanced) features of AWS Route53.&lt;/p&gt;

&lt;p&gt;From the table, we can immediately see the name of the record (first column), the record type ( A, NS, AAAA, CNAME, etc...​) and the value of the record.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J-2G7_ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AzlKeNxdll3C25dH-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J-2G7_ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AzlKeNxdll3C25dH-.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The highlighted rows are all A records. It is interesting to note how the root domain manage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The root domain itself, making redbeardlab.com point to the IP address 212.47.232.249&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sub-domain, making simplesql.redbeardlab.com point to 212.47.253.152&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All other sub-domain levels, in this case making telemetrics.redisql.redbeardlab.com point to 51.15.142.13&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ApPzwRfR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AFy0Ex2ziZBHHeowx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ApPzwRfR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AFy0Ex2ziZBHHeowx.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AAAA records are very similar to the A record.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FHv8nSfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AJAW4unet1r0zOi2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FHv8nSfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AJAW4unet1r0zOi2k.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example we make telemetrics.redisql.redbeardlab.com point to 2001:bc8:4400:2c00::2b:c17.&lt;/p&gt;

&lt;p&gt;This does not generate an ambiguity with the A record above. If the client asks for the IPv4 address the server returns 51.15.142.13. While, if the client ask for the IPv6 address the server returns 2001:bc8:4400:2c00::2b:c17. In this particular case, both addresses point to the same machine. But they could point to different servers offering completely different services.&lt;/p&gt;

&lt;p&gt;The CNAME record creates an alias.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PH-8AU32--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ANEVSy0zTpUwg-j7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PH-8AU32--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ANEVSy0zTpUwg-j7g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first example, we set the host redisql.redbeardlab.com to point to redbeardlab.github.io. In this way we can serve, under the domain we control, content from Github pages, for free. Quite convenient.&lt;/p&gt;

&lt;p&gt;In the second case we redirect all the calls to AWS Cloudfront, a CDN managed by AWS.&lt;/p&gt;

&lt;p&gt;When a client finds a CNAME it stops asking for the original host IP address and starts asking for the IP address of the ALIAS. If a client goes to redisql.redbeardlab.com, at first it will try to find the IP address of redisql.redbeardlab.com, however, the DNS server will say that the IP address does not exist, but it exists an alias, redbeardlab.github.io. At this point, the client will start looking for the IP address of redbeardlab.github.io.&lt;/p&gt;

&lt;p&gt;The TXT fields were used for verifying the ownership of the domain against Google.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NJVTujI4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A_VE6Qmlh6m8-KxfK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NJVTujI4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A_VE6Qmlh6m8-KxfK.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the most common use I encounter, but other uses for the TXT field are possible.&lt;/p&gt;

&lt;p&gt;Finally, the NS record, declare who manage the DNS entry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C08xA56r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2Awn9zLaadCjpQbC7F.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C08xA56r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2Awn9zLaadCjpQbC7F.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the DNS is managed by…​ Cloudflare. So all we said above is ignored by a real DNS client that will make its queries not against AWS Route53 but against Cloudflare.&lt;/p&gt;

&lt;p&gt;While the TTL (Time To Live) for most records is set to 300 or 600 seconds (5 to 10 minutes) the TTL for the NS is set to a much larger value, 7200 seconds (2 hours).&lt;/p&gt;

&lt;p&gt;This is to be expected, you don’t change often the NS value, once you set your DNS provider you tend to stick to it. Moreover, change the NS value is expensive, all the queries need to be directed to a completely different service that needs time to accommodate it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Note on Name Server configuration in AWS Route53
&lt;/h3&gt;

&lt;p&gt;Unfortunately, in Route53, it is not sufficient to set the Name Server record set, but it is also necessary to set the name servers in another setting.&lt;/p&gt;

&lt;p&gt;Under 'Register Domains' &amp;gt; $your_domain and then "Add or edit name servers".&lt;/p&gt;

&lt;p&gt;I find a good practice to keep the two values in sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloudflare
&lt;/h2&gt;

&lt;p&gt;Another very reputable DNS provider is Cloudflare. They don’t sell you domain names directly, but they can manage them for you.&lt;/p&gt;

&lt;p&gt;So you will need to buy your domain somewhere else, also an AWS Route53, and then let Cloudflare manage it. This is what I did above.&lt;/p&gt;

&lt;p&gt;This is done setting up the authoritative name server to point to Cloudflare. It is as simple as adding a new record (of type NS) to your existing DNS records (modulo the extra setting in AWS Route53). From that moment on, beside propagation delay, all the DNS queries will be redirected toward the new authoritative name server.&lt;/p&gt;

&lt;h3&gt;
  
  
  The console
&lt;/h3&gt;

&lt;p&gt;The console of Cloudflare is different from the one of Route53, but overall they contain the same information and it is equally simple to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IG1wPhj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AOM-qtjNBl-KtnV_i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IG1wPhj1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2048/0%2AOM-qtjNBl-KtnV_i.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can recognize the same kind of information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;the A fields that point to IPv4 addresses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the AAAA fields that point to IPv6 addresses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the CNAME used for alias&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the TXT again used for domain ownership verification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the MX used for email routing, with a priority&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The “Proxy Status” column in the Cloudflare console indicates whenever Cloudflare takes care only of the DNS ( DNS only) or also to cache and manage with their services the request to the domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Hopefully, this article is helpful if you are setting up your DNS or if you are getting started with web services.&lt;/p&gt;

&lt;p&gt;If you have any question I would love to expand the article and help you out, feel free to reach over on &lt;a href="https://twitter.com/pauldigian"&gt;twitter @pauldigian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://jr2sr.com/posts/dns/"&gt;https://jr2sr.com&lt;/a&gt; on June 7, 2020.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Always check your resources before to free them</title>
      <dc:creator>Paul DiGian</dc:creator>
      <pubDate>Wed, 29 Apr 2020 20:25:18 +0000</pubDate>
      <link>https://dev.to/digianpaul/always-check-your-resources-before-to-free-them-5gb0</link>
      <guid>https://dev.to/digianpaul/always-check-your-resources-before-to-free-them-5gb0</guid>
      <description>&lt;p&gt;Today I fixed a minor bug in our production code.&lt;/p&gt;

&lt;p&gt;The software is written in Go(lang) and makes extensive use of the &lt;code&gt;defer&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;defer&lt;/code&gt; statement, take a function invocation and run it after the current function returns.&lt;/p&gt;

&lt;p&gt;They are very handy for clean-up tasks. A classical example is the acquisition of a lock. Or closing a file.&lt;/p&gt;

&lt;p&gt;Without &lt;code&gt;defer&lt;/code&gt; you would get your resource at the beginning of the function, use it, and then clean-up.&lt;/p&gt;

&lt;p&gt;In the case of locks, you would acquire the lock, do the work in the critical section, release the lock, and the return.&lt;/p&gt;

&lt;p&gt;In case of files, you would open the file, write and read to the file, and then close the file.&lt;/p&gt;

&lt;p&gt;With this approach, every return path must be checked. As soon as you add a new return path, you must make sure that it closes all the resources it may have acquired. This is simpler to say than to do.&lt;/p&gt;

&lt;p&gt;Code bases grow larger and larger and it gets messy to check all the possible returns path. And it also looks ugly and not DRY.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;defer&lt;/code&gt; solve this problem. As soon as you get the resource you defer its cleanup. As soon as you acquire the lock, you defer the release of it. As soon as you open a file, you defer closing it.&lt;/p&gt;

&lt;p&gt;You want to put the &lt;code&gt;defer&lt;/code&gt; as close as possible to the resource initialization for two reasons.&lt;br&gt;
First of all, it is clearer when reading the code. &lt;br&gt;
Second, the closer the two calls are, the less it is likely that some hidden return path sneaks into the acquisition and the cleanup.&lt;/p&gt;

&lt;p&gt;But you don't want to put it too close. Before invoking the &lt;code&gt;defer&lt;/code&gt; you must make sure that the resource is valid.&lt;/p&gt;

&lt;p&gt;Today bug was about an HTTP call. I was making the HTTP call and immediately after I was closing its body to avoid leaking resources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;    
&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;      
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                             
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some error happened %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, sometimes, the network fails. And today it failed.&lt;/p&gt;

&lt;p&gt;The network failed, the &lt;code&gt;StatusCode&lt;/code&gt; was greater than 400 and the functions returned early. As soon as the function returned, it invoked the &lt;code&gt;defer&lt;/code&gt; statement: &lt;code&gt;resp.Body.Close()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the requested had failed, the &lt;code&gt;Body&lt;/code&gt; was not there and there was a &lt;code&gt;nil&lt;/code&gt; pointer.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;defer&lt;/code&gt; ended up calling the &lt;code&gt;Close()&lt;/code&gt; method of &lt;code&gt;nil&lt;/code&gt; and this caused a runtime panic, blowing it up in production.&lt;/p&gt;

&lt;p&gt;I corrected the code with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;                                                                                                                                                          
&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                                                                                              
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The HTTP request failed %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                         
        &lt;span class="k"&gt;return&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, I check that the request succeed. If the request succeed, the &lt;code&gt;Body&lt;/code&gt; is something we can &lt;code&gt;Close()&lt;/code&gt;, and so we can &lt;code&gt;defer&lt;/code&gt; its closing.&lt;/p&gt;

&lt;p&gt;If the request failed, for whatever reason, we return early, without deferring the close of the Body, that does not exist.&lt;/p&gt;

</description>
      <category>go</category>
      <category>defer</category>
      <category>check</category>
    </item>
  </channel>
</rss>
