<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>𝙷𝚈𝙿𝙾𝙳𝚈𝙽𝙴</title>
    <subtitle>A website where I share things</subtitle>
    <link rel="self" type="application/atom+xml" href="https://hypodyne.net/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://hypodyne.net"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-11-17T00:00:00+00:00</updated>
    <id>https://hypodyne.net/atom.xml</id>
    <entry xml:lang="en">
        <title>Visualizing Computer Hardware Topology</title>
        <published>2025-11-17T00:00:00+00:00</published>
        <updated>2025-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hypodyne.net/visualizing-computer-hardware-topology/"/>
        <id>https://hypodyne.net/visualizing-computer-hardware-topology/</id>
        
        <content type="html" xml:base="https://hypodyne.net/visualizing-computer-hardware-topology/">&lt;p&gt;There are times when you need a clear understanding of how a
computer&#x27;s hardware goes together. In my case, I&#x27;m working on a
project using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Express_Data_Path&quot;&gt;XDP&lt;&#x2F;a&gt;
to rapidly process packets in the kernel, bypassing the Linux
networking stack.&lt;&#x2F;p&gt;
&lt;p&gt;For my purposes in testing and development, it&#x27;s important to know
which network cards are connected to which CPUs. For best performance,
packet data should not cross the interconnect from one &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Non-uniform_memory_access&quot;&gt;NUMA
node&lt;&#x2F;a&gt; to
another, but should instead be handled all within the same NUMA node.&lt;&#x2F;p&gt;
&lt;p&gt;In many cases &lt;code&gt;lshw&lt;&#x2F;code&gt; does the needful, but its output is rather
verbose and one can lose sight of the forest for the trees:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;char@underbed:~$ sudo lshw | head -n 40
&lt;&#x2F;span&gt;&lt;span&gt;underbed
&lt;&#x2F;span&gt;&lt;span&gt;    description: Rack Mount Chassis
&lt;&#x2F;span&gt;&lt;span&gt;    product: PowerEdge R630 (SKU=NotProvided;ModelName=PowerEdge R630)
&lt;&#x2F;span&gt;&lt;span&gt;    vendor: Dell Inc.
&lt;&#x2F;span&gt;&lt;span&gt;    serial: 5QP0B42
&lt;&#x2F;span&gt;&lt;span&gt;    width: 64 bits
&lt;&#x2F;span&gt;&lt;span&gt;    capabilities: smbios-2.8 dmi-2.8 smp vsyscall32
&lt;&#x2F;span&gt;&lt;span&gt;    configuration: boot=normal chassis=rackmount sku=SKU=NotProvided;ModelName=PowerEdge R630 uuid=4c4c4544-0051-5010-8030-b5c04f423432
&lt;&#x2F;span&gt;&lt;span&gt;  *-core
&lt;&#x2F;span&gt;&lt;span&gt;       description: Motherboard
&lt;&#x2F;span&gt;&lt;span&gt;       product: 0CNCJW
&lt;&#x2F;span&gt;&lt;span&gt;       vendor: Dell Inc.
&lt;&#x2F;span&gt;&lt;span&gt;       physical id: 0
&lt;&#x2F;span&gt;&lt;span&gt;       version: A05
&lt;&#x2F;span&gt;&lt;span&gt;       serial: .5QP0B42.CN7475151G0196.
&lt;&#x2F;span&gt;&lt;span&gt;     *-firmware
&lt;&#x2F;span&gt;&lt;span&gt;          description: BIOS
&lt;&#x2F;span&gt;&lt;span&gt;          vendor: Dell Inc.
&lt;&#x2F;span&gt;&lt;span&gt;          physical id: 0
&lt;&#x2F;span&gt;&lt;span&gt;          version: 2.19.0
&lt;&#x2F;span&gt;&lt;span&gt;          date: 12&#x2F;12&#x2F;2023
&lt;&#x2F;span&gt;&lt;span&gt;          size: 64KiB
&lt;&#x2F;span&gt;&lt;span&gt;          capacity: 16MiB
&lt;&#x2F;span&gt;&lt;span&gt;          capabilities: isa pci pnp upgrade shadowing cdboot bootselect edd int13floppytoshiba int13floppy360 int13floppy1200 int13floppy720 int9keyboard int14serial int10video acpi usb biosbootspecification netboot uefi
&lt;&#x2F;span&gt;&lt;span&gt;     *-cpu:0
&lt;&#x2F;span&gt;&lt;span&gt;          description: CPU
&lt;&#x2F;span&gt;&lt;span&gt;          product: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz
&lt;&#x2F;span&gt;&lt;span&gt;          vendor: Intel Corp.
&lt;&#x2F;span&gt;&lt;span&gt;          physical id: 400
&lt;&#x2F;span&gt;&lt;span&gt;          bus info: cpu@0
&lt;&#x2F;span&gt;&lt;span&gt;          version: 6.63.2
&lt;&#x2F;span&gt;&lt;span&gt;          slot: CPU1
&lt;&#x2F;span&gt;&lt;span&gt;          size: 1974MHz
&lt;&#x2F;span&gt;&lt;span&gt;          capacity: 4GHz
&lt;&#x2F;span&gt;&lt;span&gt;          width: 64 bits
&lt;&#x2F;span&gt;&lt;span&gt;          clock: 3705MHz
&lt;&#x2F;span&gt;&lt;span&gt;          capabilities: lm fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp x86-64 constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc dtherm ida arat pln pts vnmi md_clear flush_l1d ibpb_exit_to_user cpufreq
&lt;&#x2F;span&gt;&lt;span&gt;          configuration: cores=8 enabledcores=8 microcode=73 threads=16
&lt;&#x2F;span&gt;&lt;span&gt;        *-cache:0
&lt;&#x2F;span&gt;&lt;span&gt;             description: L1 cache
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There&#x27;s another useful tool called &lt;code&gt;lstopo&lt;&#x2F;code&gt; that is part of the
&lt;code&gt;hwloc&lt;&#x2F;code&gt; package in many Linux distributions. &lt;code&gt;lstopo&lt;&#x2F;code&gt; creates a
visualization of the system&#x27;s layout that filters out less important
information and even elides repeating objects to reveal that forest
which &lt;code&gt;lshw&lt;&#x2F;code&gt; loses sight of. Here&#x27;s an example output from the same
system as seen above:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hypodyne.net&#x2F;visualizing-computer-hardware-topology&#x2F;.&#x2F;topo.svg&quot; alt=&quot;lstopo output visualization&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now one can clearly see what PCIe hardware is homed to which NUMA
node. Node 0 on the left has &lt;code&gt;sda&lt;&#x2F;code&gt;, my disk drive along with 2 NICs.
PCI 03:00 is a 2-port Intel 82599 10GbE NIC that I got for $15 from
eBay and PCI 01:00 is a 4-port NIC that came with the server. On Node
1, there&#x27;s another 2-port 82599 on PCI 81:00.&lt;&#x2F;p&gt;
&lt;p&gt;Along with the peripherals, you can also clearly see each NUMA node
has shared RAM, an L3 cache common to all cores, and individual L2 and
L1 caches per core.&lt;&#x2F;p&gt;
&lt;p&gt;Pretty neat!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting 3GPP Specifications</title>
        <published>2025-10-27T00:00:00+00:00</published>
        <updated>2025-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hypodyne.net/getting-3gpp-specs/"/>
        <id>https://hypodyne.net/getting-3gpp-specs/</id>
        
        <content type="html" xml:base="https://hypodyne.net/getting-3gpp-specs/">&lt;p&gt;Presently, the specifications for mobile telecom (i.e. 4G LTE, 5G,
etc.) are developed and freely published by groups working within the
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;3GPP&quot;&gt;3GPP (3rd Generation Partnership
Project)&lt;&#x2F;a&gt;. The 3GPP is sort of
analogous to the IETF (Internet Engineering Task Force), the
organization tasked with developing and promulgating internet
standards.&lt;&#x2F;p&gt;
&lt;p&gt;As a newbie in the telecom world (and the internet world too, to be
clear), I find the 3GPP&#x27;s specifications challenging to locate and
comprehend so I&#x27;ve written some notes that are hopefully useful to
myself in the future as well as others.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;getting-specification-pdfs&quot;&gt;Getting Specification PDFs&lt;&#x2F;h1&gt;
&lt;p&gt;When you already know which specification you&#x27;re looking for, head
over to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;portal.3gpp.org&#x2F;Specifications.aspx&quot;&gt;3GPP specification search
portal&lt;&#x2F;a&gt; and enter the
title or specification number in the search box.&lt;&#x2F;p&gt;
&lt;p&gt;Getting from the results page to a copy of the spec is not
straightforward.&lt;&#x2F;p&gt;
&lt;p&gt;First, click the little glasses-on-a-sheet-of-paper icon on the right
side (circled in red in the screenshot).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hypodyne.net&#x2F;getting-3gpp-specs&#x2F;.&#x2F;3gpp-search.png&quot; alt=&quot;3GPP Specification Search&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Clicking the glasses icon opens a new window where you must choose the
version of the specification you&#x27;re interested in. Select the
&lt;em&gt;Versions&lt;&#x2F;em&gt; tab and then click the green &lt;em&gt;ETSI&lt;&#x2F;em&gt; button to the right of
the version you&#x27;re interested in.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hypodyne.net&#x2F;getting-3gpp-specs&#x2F;.&#x2F;3gpp-portal-versions.png&quot; alt=&quot;Version Selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yet another window will open, this one titled &quot;Work Programme&quot;. Click
the icon circled in red under the &lt;em&gt;Download Standard&lt;&#x2F;em&gt; heading to
download a PDF of the specification (the button on the right downloads
a Word document, but I don&#x27;t recommend it because the Word files are
huge and slow to navigate compared to the PDFs).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hypodyne.net&#x2F;getting-3gpp-specs&#x2F;.&#x2F;etsi.png&quot; alt=&quot;PDF Download&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally, you&#x27;ll have your specification PDF. That was a lot of work so
you might want to save it to avoid repeating the process.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hypodyne.net&#x2F;getting-3gpp-specs&#x2F;.&#x2F;spec-pdf.png&quot; alt=&quot;Spec PDF&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tips-for-finding-the-right-specification&quot;&gt;Tips for Finding the Right Specification&lt;&#x2F;h1&gt;
&lt;p&gt;Figuring out which specification contains the information you need is
a bit more challenging. A good approach might involve reading
Wikipedia or other summaries and following their citations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;series-organization&quot;&gt;Series Organization&lt;&#x2F;h2&gt;
&lt;p&gt;The 3GPP organizes specifications into different series which are
identified by the first number the dot in the specification&#x27;s name.
For example, TS 29.244 is part of series 29. Sometimes the document
name includes a leading 1, eg. TS 129.244. I haven&#x27;t found an
explanation as to why. Drop the leading 1, if present.&lt;&#x2F;p&gt;
&lt;p&gt;These notes are mostly about the technical specification (TS)
documents, not the technical report (TR) documents. This is because I
haven&#x27;t read any TR documents yet.&lt;&#x2F;p&gt;
&lt;p&gt;Note: Series numbers &amp;lt; 21 are only about pre-LTE GSM 2G stuff, so you
can ignore them if that&#x27;s not relevant.&lt;&#x2F;p&gt;
&lt;p&gt;I am nowhere close to being an expert on the different series, but
here are my feelings on a few:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Series 21, Requirements: These are lists of other specifications
relating to a given topic. Essentially, they are an index that is
the jumping off point into the specifications you&#x27;ll need. For
example, 21.201 lists all the specifications necessary for the
Evolved Packet System (EPS).&lt;&#x2F;li&gt;
&lt;li&gt;Series 22, Service Aspects: Very high-level descriptions of &lt;em&gt;what&lt;&#x2F;em&gt; a
mobile network should do from a user or service&#x27;s perspective. These
documents are often described as &quot;stage 1&quot; descriptions. Some of the
contents seem pretty obvious if you&#x27;ve used a cell network before. I
have not read any of these yet, probably to my detriment.&lt;&#x2F;li&gt;
&lt;li&gt;Series 23, Technical Realization: These are described as &quot;stage 2&quot;
documents and seem to focus on &lt;em&gt;how&lt;&#x2F;em&gt; a network should achieve the
stuff outlined in series 22. Series 23 covers the messaging
exchanged between different entities in the network (&quot;procedures&quot;
in 3GPP jargon). These documents include diagrams showing the
ordering of messages and can be really useful for understanding how
things are supposed to work at a medium-high level. Out of the 23
series, I most often refer to TS 23.401 (E-UTRAN Access).&lt;&#x2F;li&gt;
&lt;li&gt;Series 24, 29, Signaling Protocols: So-called &quot;stage 3&quot;
descriptions. These are down-to-bits specifications for
communications protocols. They answer the &quot;how&quot; and sometimes &quot;what&quot;
but rarely &quot;why&quot; questions. Specs for GTPv2-C (TS 29.274) and PFCP
(TS 29.244) live in series 29 which covers internal network
signaling. I haven&#x27;t ready any specs in series 24, which covers
UE-network signaling (I mostly work on core network stuff). These
documents explain the semantics of a protocol and define its
messages. The protocols defined here are mentioned in the series 23
specifications. Be careful because the series 23 terms describing
the contents of a given message type can occasionally differ
slightly.&lt;&#x2F;li&gt;
&lt;li&gt;Series 36, LTE Radio Aspects: I don&#x27;t refer to these often, as I
don&#x27;t work on the radio part. I&#x27;ve skimmed parts of TS 36.300
(E-UTRAN Overall Description) a couple of times.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;pro-tips&quot;&gt;Pro-Tips&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;When learning a new specification it&#x27;s often easiest to start by
reading an early (in many cases for LTE, this is release 8) version
of the specification. Earlier versions have less extra distracting
fluff.&lt;&#x2F;li&gt;
&lt;li&gt;These specs can be really, really dense and require a lot of context
from other specs to comprehend. I&#x27;ve found that it sometimes takes
months to understand parts of a spec. It is hard, but keep at it.
Don&#x27;t be afraid to put the spec down and come back later if
something doesn&#x27;t make sense.&lt;&#x2F;li&gt;
&lt;li&gt;Keep notes in the margins of the document explaining difficult parts
of the spec or summarizing walls of text. You&#x27;ll be happy you did
when you have to come back to these parts.&lt;&#x2F;li&gt;
&lt;li&gt;First, cross-out the parts of the spec that do not apply to your
situation, if applicable. This will save tremendous time in
aggregate as you can quickly skip over irrelevant parts each time
you refer to the spec.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@QuadraticSquared&quot;&gt;Russell DeLong has posted some great lectures of LTE concepts on
his YouTube channel. I recommend watching them as an introduction to
any of the topics they
cover.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Erlang Records in Elixir</title>
        <published>2024-11-13T00:00:00+00:00</published>
        <updated>2024-11-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hypodyne.net/erlang-records-elixir/"/>
        <id>https://hypodyne.net/erlang-records-elixir/</id>
        
        <content type="html" xml:base="https://hypodyne.net/erlang-records-elixir/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;This is a post about effectively using Erlang records in Elixir code.&lt;&#x2F;p&gt;
&lt;p&gt;Lately I&#x27;ve been working on an Elixir project that uses a few Erlang
libraries that represent data using the record data type.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.erlang.org&#x2F;doc&#x2F;system&#x2F;data_types.html#record&quot;&gt;Here&#x27;s how Erlang&#x27;s documentation describes records:&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A record is a data structure for storing a fixed number of elements.
It has named fields and is similar to a struct in C. [...] record
expressions are translated to tuple expressions during compilation&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Records exist in Elixir too but are mostly there for compatibility
with Erlang (for a variety of reasons you&#x27;re better off using a struct
or a map than a record in pure Elixir code). &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;elixir&#x2F;main&#x2F;Record.html&quot;&gt;The official Elixir docs
about records&lt;&#x2F;a&gt; are brief
and left me unsure about how to actually use them, so after some
experimenting I&#x27;ve made this brief guide for reference. I hope you
find it useful!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h1&gt;
&lt;p&gt;This guide assumes basic familiarity with Elixir&#x27;s syntax, pattern
matching, and tooling. While no prior Erlang experience is required,
you should be comfortable working with Elixir&#x27;s basic data types like
tuples and maps.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;overview-of-records-in-elixir&quot;&gt;Overview of Records in Elixir&lt;&#x2F;h1&gt;
&lt;p&gt;Broadly, Elixir&#x27;s Record module lets you do two things:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1. Extract Definitions&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Extract definitions of records from existing Erlang header files into
an Elixir module as tuples. The functions &lt;code&gt;extract&#x2F;2&lt;&#x2F;code&gt; and
&lt;code&gt;extract_all&#x2F;1&lt;&#x2F;code&gt; are used for this.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;2. Generate Helpers&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generate helpers for creating, accessing, and pattern matching record
data types from tuples describing records. The macros &lt;code&gt;defrecord&#x2F;3&lt;&#x2F;code&gt;
and &lt;code&gt;defrecordp&#x2F;3&lt;&#x2F;code&gt; are used for this.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s crucial to note that you need to do both steps (extract and
define) to actually use the records defined in Erlang files inside
Elixir code. Extracting record definitions from Erlang headers results
in tuples describing the records, but does not generate the helpers
for creating, accessing, and pattern matching on records.&lt;&#x2F;p&gt;
&lt;p&gt;Simply put, you need to plumb the output of &lt;code&gt;extract&#x2F;2&lt;&#x2F;code&gt; or
&lt;code&gt;extract_all&#x2F;1&lt;&#x2F;code&gt; into &lt;code&gt;defrecord&#x2F;2&lt;&#x2F;code&gt; (or &lt;code&gt;defrecordp&#x2F;3&lt;&#x2F;code&gt;) to use Erlang
records in Elixir code.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;examples-of-extracting-and-defining-records&quot;&gt;Examples of Extracting and Defining Records&lt;&#x2F;h1&gt;
&lt;p&gt;As an example, the code below extracts the &lt;code&gt;:gtp&lt;&#x2F;code&gt; record type from the
library &lt;code&gt;gtp_packet.hrl&lt;&#x2F;code&gt; and puts a tuple defining the record into
&lt;code&gt;gtp_def&lt;&#x2F;code&gt;. Then, &lt;code&gt;:gtp&lt;&#x2F;code&gt; and &lt;code&gt;gtp_def&lt;&#x2F;code&gt; are passed to
&lt;code&gt;Record.defrecord&#x2F;3&lt;&#x2F;code&gt; to generate code for using the &lt;code&gt;gtp&lt;&#x2F;code&gt; record type:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;  gtp_def = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;.extract(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:gtp&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;from_lib: &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;gtplib&#x2F;include&#x2F;gtp_packet.hrl&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;.defrecord(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:gtp&lt;&#x2F;span&gt;&lt;span&gt;, gtp_def) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# generates the macros gtp&#x2F;0, gtp&#x2F;1, gtp&#x2F;2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Extracting and defining records can get really tedious if you find
yourself working with many different record types. Thankfully, Elixir
also provides a way to extract records in bulk from Erlang headers.
Unfortunately, there&#x27;s no way to define record helpers in bulk.
However, the &lt;code&gt;Enum&lt;&#x2F;code&gt; module and a simple lambda function comes to the
rescue!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;  # Define helpers dynamically based on the extracted records
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span&gt;.each(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;.extract_all(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;from_lib: &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;gtplib&#x2F;include&#x2F;gtp_packet.hrl&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;{name, fields} -&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;.defrecord(name, fields)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each tuple from &lt;code&gt;extract_all&#x2F;2&lt;&#x2F;code&gt; of &lt;code&gt;{name, fields}&lt;&#x2F;code&gt;, where &lt;code&gt;name&lt;&#x2F;code&gt; is
simply the name of the record and &lt;code&gt;fields&lt;&#x2F;code&gt; is a tuple describing the
record&#x27;s fields is passed into &lt;code&gt;defrecord&#x2F;3&lt;&#x2F;code&gt; just as in the
manually-done first example we saw earlier. I think it&#x27;s kind of
strange there&#x27;s no &lt;code&gt;extract_and_define&lt;&#x2F;code&gt; function in Elixir that does
this all for you, but whatever, this way gives you a little more
control over things (for example, you could modify the names, such as
putting a prefix on them, to avoid a collision if you&#x27;re importing
records from several different Erlang libraries into the same Elixir
module).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;using-records-in-elixir&quot;&gt;Using Records in Elixir&lt;&#x2F;h1&gt;
&lt;p&gt;After you&#x27;ve managed to generate code for working with records using
&lt;code&gt;defrecord&#x2F;3&lt;&#x2F;code&gt; you can finally use them! If you called
&lt;code&gt;defrecord(:foo, foo_defs)&lt;&#x2F;code&gt; (where &lt;code&gt;foo_defs&lt;&#x2F;code&gt; was returned from &lt;code&gt;extract&#x2F;2&lt;&#x2F;code&gt;)
you&#x27;d end up with three new macros all named &lt;code&gt;foo&lt;&#x2F;code&gt;. Let&#x27;s imagine the record
type &lt;code&gt;foo&lt;&#x2F;code&gt; contains the fields &lt;code&gt;bar&lt;&#x2F;code&gt; and &lt;code&gt;baz&lt;&#x2F;code&gt;. In fact, you can do all this
in &lt;code&gt;iex&lt;&#x2F;code&gt; as long as you wrap in inside a module definition:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defmodule &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;...&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Record&lt;&#x2F;span&gt;&lt;span&gt;.defrecord(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:undefined&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:undefined&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;...&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;creating-records&quot;&gt;Creating Records&lt;&#x2F;h2&gt;
&lt;p&gt;Now let&#x27;s use &lt;code&gt;foo&#x2F;0&lt;&#x2F;code&gt; to create a &lt;code&gt;foo&lt;&#x2F;code&gt; record with default values
(spoiler: it&#x27;s boring, but it&#x27;s a start):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo()
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:undefined&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:undefined&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice the result is a tuple starting with &lt;code&gt;:foo&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To make things a little more interesting we can set values in the
&lt;code&gt;foo&lt;&#x2F;code&gt; we&#x27;re creating:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 1234&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;inspecting-records&quot;&gt;Inspecting Records&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s say we have a record like &lt;code&gt;{:foo, :asdf, 1234}&lt;&#x2F;code&gt; and that we&#x27;re
forgetful and can&#x27;t remember the order of &lt;code&gt;bar&lt;&#x2F;code&gt; and &lt;code&gt;baz&lt;&#x2F;code&gt; inside the
record. We can use the &lt;code&gt;foo&#x2F;1&lt;&#x2F;code&gt; macro generated by &lt;code&gt;defrecord&#x2F;2&lt;&#x2F;code&gt;
earlier to see the keys and the values laid out clearly:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo({&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;})
&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 1234&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;accessing-a-field-within-records&quot;&gt;Accessing a Field within Records&lt;&#x2F;h2&gt;
&lt;p&gt;You can access individual fields within a record using square
brackets, similarly to a Map. To do this, you pass the tuple
representation of a record into the generated function with 1-arity,
here &lt;code&gt;foo&#x2F;1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; my_foo = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 1234&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo)[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:bar&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo)[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:baz&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The generated 2-arity function &lt;code&gt;foo&#x2F;2&lt;&#x2F;code&gt; allows for the same with
slightly different syntax:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:bar&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:baz&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can clearly see that &lt;code&gt;bar&lt;&#x2F;code&gt; is set to &lt;code&gt;asdf&lt;&#x2F;code&gt; and &lt;code&gt;baz&lt;&#x2F;code&gt; is set to
&lt;code&gt;1234&lt;&#x2F;code&gt;. This technique can come in really handy for working with
records in the repl if you want to inspect them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pattern-matching-on-records&quot;&gt;Pattern Matching on Records&lt;&#x2F;h2&gt;
&lt;p&gt;However, we can go further and even pattern match on fields within
records with similar syntax to pattern matching on Maps. Taking the
same &lt;code&gt;foo&lt;&#x2F;code&gt; example record as before, &lt;code&gt;bar&lt;&#x2F;code&gt; and &lt;code&gt;baz&lt;&#x2F;code&gt; can be pattern
matched into their own variables:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; my_foo = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 1234&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar:&lt;&#x2F;span&gt;&lt;span&gt; bar, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz:&lt;&#x2F;span&gt;&lt;span&gt; baz) = my_foo
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; bar
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; baz
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pattern matching is very useful if an Erlang library hands you a
record from which you want to concisely extract multiple values.
Pattern matching can also be done in function heads to select a
specific implementation of a function based on the values of its
inputs. For more details on pattern matching see the Elixir docs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updating-records&quot;&gt;Updating Records&lt;&#x2F;h2&gt;
&lt;p&gt;Finally, you can update fields in an existing record (leaving other
fields untouched) using the 2-arity version of the generated macro,
again &lt;code&gt;foo&#x2F;2&lt;&#x2F;code&gt; here:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;iex&amp;gt; my_foo = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 1234&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:asdf&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:qwerty&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:qwerty&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1234&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;iex&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Foo&lt;&#x2F;span&gt;&lt;span&gt;.foo(my_foo, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;bar: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:qwerty&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;baz: 5678&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:foo&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:qwerty&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;5678&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h1&gt;
&lt;p&gt;I&#x27;ve tried to show in detail with plenty of examples how to use the
functionality of Elixir&#x27;s &lt;code&gt;Record&lt;&#x2F;code&gt; module. This includes extracting
record definitions from Erlang header files using &lt;code&gt;extract&#x2F;2&lt;&#x2F;code&gt; and
&lt;code&gt;extract_all&#x2F;2&lt;&#x2F;code&gt;, generating macros for working with records via
&lt;code&gt;defrecord&#x2F;3&lt;&#x2F;code&gt; and &lt;code&gt;defrecordp&#x2F;3&lt;&#x2F;code&gt;, and examples of how to read, write,
and update record data types in the previous few subsections.&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this guide fills in the gaps in the official documentation
and makes at least one other person&#x27;s life a little easier.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tunnels Within Tunnels: One Weird Trick for Free IP Transit</title>
        <published>2023-10-28T00:31:47-07:00</published>
        <updated>2023-10-28T00:31:47-07:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hypodyne.net/tunnels-within-tunnels/"/>
        <id>https://hypodyne.net/tunnels-within-tunnels/</id>
        
        <content type="html" xml:base="https://hypodyne.net/tunnels-within-tunnels/">&lt;p&gt;&lt;em&gt;2023-11-16 update: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;johnelliott.org&#x2F;blog&#x2F;tunnelbroker-mikrotik&#x2F;&quot;&gt;John Elliott published a post with router configuration
details&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you took your homelab hobby to the next level by acquiring an
ASN. You don&#x27;t have much money, but you&#x27;ve still managed to connect to
an IXP and peer with other ASs over the exchange fabric. You&#x27;d like to
connect your network back to sites scattered across a metro region,
often with only consumer internet connections because other types of
service are too expensive.&lt;&#x2F;p&gt;
&lt;p&gt;You may want to network the sites together and may also want the
sites&#x27; internet-bound traffic to exit through your own AS (there are a
number of reasons you might want to do this --see the last section).
Hence, you decide to set up VPN tunnels between your sites and your
network equipment at the IXP.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, the large regional ISPs servicing your sites will not
peer with you because you are small fry, so the tunneled traffic
doesn&#x27;t reach your router at the IXP via settlement-free peering
relationships, instead it goes through a paid &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.thousandeyes.com&#x2F;learning&#x2F;techtorials&#x2F;transit-provider&quot;&gt;upstream transit
provider&lt;&#x2F;a&gt;.
You don&#x27;t want to increase the traffic through your transit provider
more than you have to because it&#x27;s expensive and limited. Is there a
solution?&lt;&#x2F;p&gt;
&lt;p&gt;Recently, while tinkering with VPN tunnels with other volunteers from
the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seattlecommunitynetwork.org&quot;&gt;Seattle Community Network&lt;&#x2F;a&gt;
(eg. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;johnelliott.org&#x2F;&quot;&gt;John Elliott&lt;&#x2F;a&gt;), I had a sudden flash of
inspiration. An &lt;em&gt;absurd&lt;&#x2F;em&gt; idea emerges...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enter-the-hurricane-electric-free-ipv6-tunnel-broker&quot;&gt;Enter the Hurricane Electric Free IPv6 Tunnel Broker&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tunnelbroker.net&#x2F;&quot;&gt;The Hurricane Electric Free IPv6 Tunnel
Broker&lt;&#x2F;a&gt; is a free service that HE provides
out of the goodness of their hearts. If your ISP&#x27;s IPv6 service is
lacking or nonexistent, no problem! HE will generously lend you a &#x2F;64
IPv6 address block and provide you with a tunnel endpoint address
where you can send IPv6 using RFC-compliant 6to4 technology!&lt;&#x2F;p&gt;
&lt;p&gt;For costing nothing, HE&#x27;s IPv6 service is
&lt;em&gt;amazing&lt;&#x2F;em&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#tunnel-downsides&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Here in Seattle on a Centurylink
connection HE&#x27;s tunnel broker generally outperforms Centurylink&#x27;s own
6rd service. And unlike 6rd, the HE IPv6 block is static, making it
far more useful for running servers at home.&lt;&#x2F;p&gt;
&lt;p&gt;Besides providing free IPv6 forwarding, Hurricane Electric also freely
peers with other networks at exchange points, no matter the size.&lt;&#x2F;p&gt;
&lt;p&gt;Hmm... Could we use HE&#x27;s network to bypass an upstream transit
provider?&lt;&#x2F;p&gt;
&lt;p&gt;It turns out &lt;em&gt;yes, and the performance is much better than any of us
expected.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;A disclaimer: Don&#x27;t abuse this. There are also some details about
why this is kind of technically icky&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#bad-performance&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. But we had to
see whether it worked (and how badly).&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Read on...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-initial-configuration-via-paid-upstream-transit-provider&quot;&gt;The Initial Configuration (via Paid Upstream Transit Provider)&lt;&#x2F;h2&gt;
&lt;p&gt;The inital tunneling config is pretty straightforward. We&#x27;re running a
VPN tunnel endpoint on one of our servers at the IXP. Internet-bound
traffic is NATted with an address from our public IPv4 block.&lt;&#x2F;p&gt;
&lt;p&gt;Routers at the remote sites connect to the VPN endpoint at the IXP.
Internet-bound traffic is routed to the IXP via the tunnel, unless the
tunnel is down because we messed something up, in which case traffic
bypasses the tunnel and directly egresses via the consumer ISP
connection as a fail-over.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wireguard.com&#x2F;&quot;&gt;WireGuard&lt;&#x2F;a&gt; for these tunnels.
So far WireGuard has been simple to configure (though there are a few
quirks), fast, and ...fast. MikroTik&#x27;s RouterOS 7, released in the
last year, supports WireGuard, allowing us to finally use it on our
MikroTik hardware. Other volunteers, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;johnelliott.org&#x2F;&quot;&gt;John
Elliott&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;homes.cs.washington.edu&#x2F;~infrared&#x2F;&quot;&gt;Esther
Jang&lt;&#x2F;a&gt;, did the bulk of the
work figuring out the WireGuard and firewall configurations.&lt;&#x2F;p&gt;
&lt;p&gt;John used iperf to achieve a respectable 860 Mbps over the tunnel
between his home 940 Mbps GPON connection to the VPN server.&lt;&#x2F;p&gt;
&lt;p&gt;These are two traceroutes from different consumer ISPs showing that
the path taken to our test server includes a hop through an upstream
transit provider (AS1299):&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ mtr -w -r -z -c 5 23.146.168.1
&lt;&#x2F;span&gt;&lt;span&gt;HOST: foo                                        Loss%   Snt   Last   Avg  Best  Wrst StDev
&lt;&#x2F;span&gt;&lt;span&gt;1. AS???    rb5000.home.arpa                      0.0%     5    2.1   1.0   0.7   2.1   0.6
&lt;&#x2F;span&gt;&lt;span&gt;2. AS209    tukw-dsl-gw69.tukw.qwest.net          0.0%     5    3.2   3.0   2.9   3.2   0.2
&lt;&#x2F;span&gt;&lt;span&gt;3. AS209    63-226-198-33.tukw.qwest.net          0.0%     5    3.0   3.3   2.1   5.1   1.1
&lt;&#x2F;span&gt;&lt;span&gt;4. AS???    ???                                  100.0     5    0.0   0.0   0.0   0.0   0.0
&lt;&#x2F;span&gt;&lt;span&gt;5. AS3356   4.69.219.210                          0.0%     5    3.5   3.6   3.3   3.9   0.3
&lt;&#x2F;span&gt;&lt;span&gt;6. AS1299   sea-b1-link.ip.twelve99.net           0.0%     5    3.5   3.8   3.5   4.3   0.3
&lt;&#x2F;span&gt;&lt;span&gt;7. AS1299   doof-ic-375811.ip.twelve99-cust.net   0.0%     5    3.5   3.4   3.1   3.6   0.2
&lt;&#x2F;span&gt;&lt;span&gt;8. AS54429  seattlecommunitynetwork.org           0.0%     5    3.8   3.6   3.5   3.8   0.1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;A traceroute from a Centurylink residential connection to our router
at the SIX transits 1299.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ mtr -w -r -z -c 5 23.146.168.1
&lt;&#x2F;span&gt;&lt;span&gt;HOST: bar                                                       Loss%   Snt   Last   Avg  Best  Wrst StDev
&lt;&#x2F;span&gt;&lt;span&gt;  1. AS???    router.asus.com                                    0.0%     5    1.2   3.2   1.2   9.2   3.4
&lt;&#x2F;span&gt;&lt;span&gt;  2. AS???    100.92.123.67                                      0.0%     5    8.9  11.6   8.9  16.6   3.0
&lt;&#x2F;span&gt;&lt;span&gt;  3. AS7922   po-323-406-rur302.seattle.wa.seattle.comcast.net   0.0%     5   13.1  11.8   9.6  14.1   2.0
&lt;&#x2F;span&gt;&lt;span&gt;  4. AS7922   po-300-xar02.seattle.wa.seattle.comcast.net        0.0%     5    9.9  11.4   8.6  15.4   2.6
&lt;&#x2F;span&gt;&lt;span&gt;  5. AS7922   be-304-arsc1.seattle.wa.seattle.comcast.net        0.0%     5    9.7  17.4   9.7  29.9   7.8
&lt;&#x2F;span&gt;&lt;span&gt;  6. AS7922   be-36131-cs03.seattle.wa.ibone.comcast.net         0.0%     5   10.2  15.0  10.2  31.1   9.0
&lt;&#x2F;span&gt;&lt;span&gt;  7. AS7922   be-2313-pe13.seattle.wa.ibone.comcast.net          0.0%     5   12.5  10.9  10.1  12.5   1.0
&lt;&#x2F;span&gt;&lt;span&gt;  8. AS7922   50.208.233.194                                    40.0%     5   32.0  25.1  20.8  32.0   6.0
&lt;&#x2F;span&gt;&lt;span&gt;  9. AS???    ???                                               100.0     5    0.0   0.0   0.0   0.0   0.0
&lt;&#x2F;span&gt;&lt;span&gt; 10. AS1299   doof-ic-375811.ip.twelve99-cust.net                0.0%     5   15.1  14.7  10.4  25.1   6.1
&lt;&#x2F;span&gt;&lt;span&gt; 11. AS54429  seattlecommunitynetwork.org                        0.0%     5    9.8  15.2   9.8  35.5  11.3
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;A traceroute from a Comcast residential connection&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#RFC6598&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to our router
at the SIX hops through 1299 too.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This cutesy diagram shows roughly the same information as the
traceroutes but with a larger font and some arrows.&lt;&#x2F;p&gt;
&lt;div class=&quot;svg-figure&quot;&gt;
    &lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 673.857 278.463&quot;&gt;&lt;defs&gt;&lt;style&gt;@font-face{font-family:&amp;quot;Virgil&amp;quot;;src:url(&#x2F;fonts&#x2F;Virgil.woff2)}&lt;&#x2F;style&gt;&lt;&#x2F;defs&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M73.8 118.797c9.26-.51 19.96 3.72 28.59 8.64 8.63 4.91 17.87 12.65 23.18 20.85 5.31 8.2 7.99 18.78 8.68 28.35.68 9.57-.85 20.3-4.59 29.05-3.73 8.76-10.43 17.45-17.84 23.47s-17.28 10.54-26.63 12.66c-9.35 2.12-20.16 2.58-29.47.05-9.31-2.53-19.49-8.52-26.37-15.23-6.89-6.7-11.75-16.03-14.95-24.99-3.2-8.97-5.5-19.27-4.26-28.81 1.25-9.54 5.97-20.66 11.73-28.43 5.76-7.76 13.61-14.04 22.83-18.14 9.22-4.1 26.54-5.57 32.47-6.44 5.93-.87 3.01.18 3.09 1.21m-24.04-.03c8.44-3.15 20.65-2.37 30.32.01 9.67 2.37 20.52 8.03 27.72 14.25 7.2 6.22 12.16 14.11 15.5 23.07 3.33 8.96 5.4 20.99 4.49 30.69-.92 9.71-4.68 19.55-9.97 27.56-5.28 8.02-13.17 16.13-21.76 20.53-8.58 4.39-19.89 6.08-29.75 5.83s-20.83-3.02-29.41-7.34c-8.57-4.31-16.38-10.82-22.07-18.55-5.68-7.73-11-18.14-12.06-27.84-1.05-9.69 2.04-21.48 5.75-30.34s9.57-16.41 16.52-22.8c6.96-6.39 20.9-13.24 25.21-15.53 4.31-2.29.25.79.67 1.81&quot;&#x2F;&gt;&lt;text x=&quot;36.225&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(36.06 146.556)&quot;&gt;user &lt;&#x2F;text&gt;&lt;text x=&quot;36.225&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(36.06 146.556)&quot;&gt;site&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M230.068 20.527c10.56 2.37 21.68 9.38 29.74 15.7 8.07 6.33 15.32 14.25 18.66 22.26 3.34 8 3.33 17.16 1.36 25.76-1.96 8.59-6.64 18.49-13.14 25.81-6.5 7.32-15.82 13.69-25.83 18.09-10.01 4.4-22.7 7.6-34.23 8.32-11.52.72-24.44-.67-34.92-4.01s-20.16-9.69-27.94-16.01c-7.78-6.32-15.28-13.68-18.71-21.89-3.44-8.22-3.44-18.83-1.92-27.42 1.52-8.59 4.78-17.17 11.04-24.13 6.26-6.97 16.54-13.14 26.54-17.64 9.99-4.5 20.67-9.16 33.43-9.38 12.76-.22 34.82 6.09 43.13 8.07 8.31 1.98 7.13 3.02 6.75 3.8m-41.58-12.36c10.96-.74 24.68 3.52 35.16 7.76 10.47 4.25 20.82 11.04 27.68 17.71 6.86 6.67 11.21 14.03 13.47 22.3 2.27 8.27 3.04 18.7.13 27.33-2.91 8.62-10.43 17.82-17.58 24.43-7.16 6.61-15.31 11.83-25.34 15.22-10.02 3.4-22.97 5.27-34.81 5.16-11.84-.11-25.43-1.91-36.23-5.8-10.81-3.89-21.56-10.56-28.6-17.53-7.04-6.96-11.6-15.72-13.63-24.27-2.04-8.55-1.55-18.89 1.42-27.04 2.96-8.15 9.19-15.23 16.35-21.87 7.15-6.64 16.19-14.21 26.57-17.97 10.38-3.75 29.66-4.15 35.71-4.54 6.05-.39.38 1.25.57 2.2&quot;&#x2F;&gt;&lt;text x=&quot;49.833&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151.411 38.99)&quot;&gt;centurylink&lt;&#x2F;text&gt;&lt;text x=&quot;49.833&quot; y=&quot;25&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151.411 38.99)&quot;&gt;or &lt;&#x2F;text&gt;&lt;text x=&quot;49.833&quot; y=&quot;50&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151.411 38.99)&quot;&gt;something&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M355.099 140.623c11.58 2.25 24.68 10.23 33.61 16.86 8.93 6.63 15.76 14.51 19.98 22.93 4.23 8.42 6.81 18.44 5.38 27.59-1.43 9.16-7.01 19.64-13.94 27.33-6.93 7.69-16.71 14.22-27.64 18.81-10.92 4.59-25.23 8-37.92 8.74-12.68.75-26.27-1.18-38.19-4.26-11.93-3.09-24.49-7.83-33.38-14.26-8.88-6.43-15.99-15.75-19.93-24.32-3.94-8.56-5.19-18.05-3.7-27.05 1.48-9.01 5.82-19.39 12.6-26.99 6.79-7.61 17.36-14.12 28.1-18.64 10.73-4.52 21.49-8.31 36.31-8.49 14.82-.18 42.09 5.11 52.6 7.43 10.5 2.32 11.21 5.78 10.44 6.49m-15.4-9.96c11.82 2.62 24.05 10.89 31.85 18.1 7.8 7.21 12.12 16.08 14.95 25.17 2.84 9.08 4.69 20.48 2.06 29.34-2.63 8.85-9.84 16.87-17.86 23.79-8.02 6.91-18.94 13.73-30.26 17.7-11.32 3.98-24.86 6.16-37.66 6.15-12.81-.01-27.51-2.24-39.17-6.2-11.67-3.96-22.77-10.73-30.83-17.56-8.06-6.83-14.97-14.67-17.53-23.43-2.56-8.76-.81-19.93 2.18-29.12 2.98-9.19 8.08-19.06 15.71-26.02 7.64-6.95 18.48-11.95 30.09-15.71 11.61-3.76 26.6-6.73 39.56-6.85 12.95-.13 32.17 5.08 38.17 6.11 6 1.04-1.57-.87-2.17.1&quot;&#x2F;&gt;&lt;text x=&quot;54.75&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(271.369 165.563)&quot;&gt;as1299 &lt;&#x2F;text&gt;&lt;text x=&quot;54.75&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(271.369 165.563)&quot;&gt;(arelion)&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M504.542 12.46c13.52.86 27.44 4.55 38.95 9.22 11.51 4.67 22.42 11.85 30.13 18.83 7.71 6.98 13.57 15.17 16.12 23.05 2.55 7.88 2.48 16.32-.81 24.21-3.29 7.89-10.53 16.42-18.94 23.13-8.42 6.72-19.42 12.95-31.56 17.15-12.14 4.2-27.33 6.71-41.27 8.05-13.94 1.34-28.81 1.78-42.37-.03-13.56-1.81-27.28-5.99-38.99-10.81-11.72-4.83-23.55-11.43-31.29-18.12-7.75-6.69-12.95-14.17-15.2-22.03-2.26-7.87-1.68-17.19 1.67-25.16 3.35-7.97 10.15-15.83 18.44-22.68 8.29-6.84 19.43-13.87 31.3-18.41 11.87-4.53 25.1-7.67 39.93-8.79 14.84-1.11 40.05 1.3 49.1 2.1 9.06.8 5.73 1.55 5.24 2.71m1.35-1.04c13.42 1.69 28.44 6.27 38.97 11.89 10.54 5.61 18.28 14.29 24.25 21.82 5.98 7.52 10.64 15.2 11.61 23.31.96 8.12-1.06 17.62-5.82 25.36-4.76 7.74-13.26 15.1-22.72 21.06-9.46 5.96-20.98 11.14-34.04 14.7-13.06 3.57-30.1 6.19-44.32 6.69-14.22.5-27.57-1.02-41.02-3.7-13.44-2.68-29.07-7.01-39.64-12.37-10.58-5.37-18-12.32-23.81-19.8-5.82-7.48-9.95-16.54-11.09-25.1-1.13-8.56-.55-18.51 4.27-26.28 4.82-7.77 14.8-14.4 24.65-20.32 9.86-5.91 21.63-11.69 34.49-15.16 12.86-3.47 28.77-5.15 42.67-5.67 13.9-.51 33.77 1.67 40.75 2.57 6.98.9 1.52 1.85 1.11 2.86&quot;&#x2F;&gt;&lt;text x=&quot;73.858&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(405.758 38.697)&quot;&gt;as395823&lt;&#x2F;text&gt;&lt;text x=&quot;73.858&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(405.758 38.697)&quot;&gt;(doof)&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M536.832 154.777c11.06-3.19 26.69-3.24 39.78-2.7 13.08.54 27.3 2.19 38.73 5.94 11.44 3.74 22.35 10.1 29.87 16.54 7.52 6.43 12.56 14.4 15.26 22.07 2.7 7.67 3.37 16.27.95 23.94-2.42 7.67-8.34 15.54-15.47 22.08-7.12 6.54-16.53 12.9-27.28 17.17-10.75 4.27-24.39 7.43-37.22 8.44-12.83 1-27.22-.1-39.76-2.42s-25.72-6.42-35.47-11.53c-9.74-5.11-17.67-11.96-23-19.15-5.34-7.18-8.88-16.08-9-23.95-.13-7.87 3.33-15.85 8.24-23.25 4.92-7.4 11.66-15.45 21.26-21.13 9.59-5.68 29.69-10.97 36.3-12.96 6.6-2 2.81.16 3.32.97m50.89-1.23c12.25 1.53 24.97 7.43 34.98 12.31 10.01 4.88 19.56 9.86 25.08 16.97 5.52 7.11 7.63 17.64 8.03 25.69.4 8.06-.82 15.32-5.62 22.65-4.81 7.32-14.13 15.51-23.2 21.31-9.08 5.8-19.19 10.88-31.26 13.49-12.07 2.62-28.41 3.1-41.15 2.19-12.74-.92-24.35-3.83-35.3-7.66-10.95-3.83-22.44-9.15-30.41-15.34-7.97-6.19-13.97-14.2-17.4-21.82-3.43-7.62-5.44-16.01-3.19-23.9 2.26-7.89 9.15-16.97 16.7-23.46 7.55-6.5 18.14-11.4 28.6-15.51 10.46-4.11 21.5-8.06 34.17-9.14 12.68-1.08 35.1 2.23 41.88 2.64 6.78.42-.7-1.07-1.21-.14&quot;&#x2F;&gt;&lt;text x=&quot;62&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(506.882 174.793)&quot;&gt;as54429&lt;&#x2F;text&gt;&lt;text x=&quot;62&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(506.882 174.793)&quot;&gt;(us)&lt;&#x2F;text&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M100.124 126.087c5.22-4.07 25.46-19.85 30.57-23.71m-31 24.58c5.4-3.8 26.53-19.93 31.87-24.06&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M120.514 118.817c2.28-3.24 5.34-6.6 10.98-16.25m-10.18 16.9c2.39-4.36 4.61-8.08 10.11-16.85&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M112.344 108.157c3.97-1.11 8.68-2.33 19.15-5.59m-18.34 6.24c4.45-1.71 8.7-2.77 18.27-6.19&quot;&#x2F;&gt;&lt;&#x2F;g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M242.94 118.633c5.91 4.95 29.34 25.26 35.2 30.24m-35.83-29.28c5.89 4.8 29.68 23.65 35.61 28.58&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M255.66 141.513c7.29 1.8 12.31 2.75 21.94 6.29m-21.01-7.01c7.96 2.34 15.67 5.37 21.51 7.71&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M265.46 129.403c4.74 4.98 7.18 9.11 12.14 18.4m-11.21-19.12c4.29 6.85 8.37 14.37 11.71 19.82&quot;&#x2F;&gt;&lt;&#x2F;g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M367.86 141.427c4.59-4.06 22.99-20.33 27.52-24.41m-27.95 24.2c4.54-4.02 23.18-19.71 27.73-23.7&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M386.88 133.867c2.08-6.07 4.98-11.79 8.21-15.85m-8.62 15.02c1.98-3.94 4.4-8.17 8.6-15.6&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M378.78 124.417c4.91-2.82 10.61-5.27 16.31-6.4m-16.72 5.57c4.1-1.46 8.66-3.19 16.7-6.15&quot;&#x2F;&gt;&lt;&#x2F;g&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M507.048 132.108c2.72 4.55 13.53 22.79 16.33 27.4m-16.75-27.62c2.64 4.59 13.55 22.43 16.4 26.99&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M510.808 148.838c4.09 4 8.69 6.15 12.38 9.9m-12.93-9.97c4.62 3.77 9.17 7.22 12.82 10.04&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M520.138 143.078c.99 5.93 2.47 10.01 3.05 15.66m-3.59-15.74c1.3 5.8 2.53 11.3 3.48 15.81&quot;&#x2F;&gt;&lt;&#x2F;g&gt;&lt;&#x2F;svg&gt;

&lt;&#x2F;div&gt;

&lt;h2 id=&quot;the-path-to-the-hurricane-electric-ipv6-tunnel-broker&quot;&gt;The Path to the Hurricane Electric IPv6 Tunnel Broker&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s do a few more traceroutes to see the path the traffic takes.
We&#x27;ll start with an IPv6 traceroute over the HE IPv6 tunnel broker to
Seattle Community Network&#x27;s router (2602:fd94::1) at the Seattle
Internet Exchange:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;[asdf@rb5] &amp;gt; &#x2F;tool&#x2F;traceroute 2602:fd94::1
&lt;&#x2F;span&gt;&lt;span&gt;Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
&lt;&#x2F;span&gt;&lt;span&gt;#  ADDRESS            LOSS  SENT  LAST     AVG  BEST  WORST  STD-DEV
&lt;&#x2F;span&gt;&lt;span&gt;1  2001:470:a:f00::1  0%     101  4ms      4.4  2.8   31.9   2.9
&lt;&#x2F;span&gt;&lt;span&gt;2                     100%   101  timeout
&lt;&#x2F;span&gt;&lt;span&gt;3  2602:fd94::1       0%     100  3.2ms    4    2.1   67.7   6.5
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;(First hop IP address slightly redacted)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This traceroute doesn&#x27;t show hostnames or AS numbers, but that&#x27;s ok.
What&#x27;s notable is that this traffic seems to hop right into our
network, after a mystery hop at hop #2 that I suspect is some
HE-internal stuff we can&#x27;t see. It appears traffic enters HE&#x27;s network
via their IPv6 tunnel broker then passes through the peering
connection between HE and our router at the IXP, rather than going
through a transit provider. This makes sense because the peering link
should have fewer hops, seeing as the traffic is already inside HE&#x27;s
network.&lt;&#x2F;p&gt;
&lt;p&gt;That last traceroute was run inside the tunnel so it doesn&#x27;t show any
of the hops that happen before the packets reach HE. To see the path
taken by the tunnel itself, in other words the outside view, we can
run traceroute to the IPv4 address of our HE tunnel broker endpoint
216.218.226.238.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example of an outside-the-tunnel traceroute to the HE tunnel
broker endpoint taken from a Comcast residential connection. Pay
attention to the AS numbers, you can see that Comcast (AS7922)
connects to Hurricane Electric (AS6939) without an intermediate hop.
Looks like they peer with each other.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ mtr -w -r -z -c 5 216.218.226.238
&lt;&#x2F;span&gt;&lt;span&gt;HOST: bar                                                       Loss%   Snt   Last   Avg  Best  Wrst StDev
&lt;&#x2F;span&gt;&lt;span&gt;  1. AS???    router.asus.com                                    0.0%     5    2.3   3.0   1.2   7.5   2.6
&lt;&#x2F;span&gt;&lt;span&gt;  2. AS???    100.92.123.67                                      0.0%     5   10.2  11.1   8.7  14.4   2.1
&lt;&#x2F;span&gt;&lt;span&gt;  3. AS7922   po-323-406-rur302.seattle.wa.seattle.comcast.net   0.0%     5   16.0  11.5   9.8  16.0   2.6
&lt;&#x2F;span&gt;&lt;span&gt;  4. AS7922   po-300-xar02.seattle.wa.seattle.comcast.net        0.0%     5   12.1  10.9   9.0  12.2   1.4
&lt;&#x2F;span&gt;&lt;span&gt;  5. AS7922   be-304-arsc1.seattle.wa.seattle.comcast.net        0.0%     5   11.9  13.7   9.8  20.1   3.9
&lt;&#x2F;span&gt;&lt;span&gt;  6. AS7922   be-36131-cs03.seattle.wa.ibone.comcast.net        60.0%     5   13.6  12.1  10.5  13.6   2.1
&lt;&#x2F;span&gt;&lt;span&gt;  7. AS7922   be-2313-pe13.seattle.wa.ibone.comcast.net          0.0%     5   21.9  14.0  10.2  21.9   5.0
&lt;&#x2F;span&gt;&lt;span&gt;  8. AS7922   50.208.233.194                                    20.0%     5   28.1  20.7  10.5  31.1  10.4
&lt;&#x2F;span&gt;&lt;span&gt;  9. AS6939   tserv1.sea1.he.net                                 0.0%     5   11.7  10.4   9.8  11.7   0.8
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;An &lt;code&gt;mtr&lt;&#x2F;code&gt; traceroute from a Comcast residential connection to the
Hurricane Electric Free IPv6 Tunnel Broker&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cramming-tunnels-inside-tunnels&quot;&gt;Cramming Tunnels Inside Tunnels&lt;&#x2F;h2&gt;
&lt;p&gt;The last piece is getting the user traffic to take the path through HE
shown above. Briefly, we&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Set up HE free IPv6 tunnels at user sites.&lt;&#x2F;li&gt;
&lt;li&gt;Send site traffic over an &lt;strong&gt;IPv6-addressed&lt;&#x2F;strong&gt; VPN to our network.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In other words, we put a VPN tunnel &lt;em&gt;inside&lt;&#x2F;em&gt; HE&#x27;s 6to4 tunnel. Our
inner VPN tunnel must be destined to an IPv6 address so that it goes
inside the HE 6to4 tunnel. However, the traffic inside our innermost
tunnel can still use IPv4.&lt;&#x2F;p&gt;
&lt;p&gt;Traffic takes a path that looks something like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;svg-figure&quot;&gt;
    &lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 674 466&quot;&gt;&lt;defs&gt;&lt;style&gt;@font-face{font-family:&amp;quot;Virgil&amp;quot;;src:url(&#x2F;fonts&#x2F;Virgil.woff2)}&lt;&#x2F;style&gt;&lt;&#x2F;defs&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M74 306c9 0 20 4 28 9 9 5 18 13 24 21 5 8 8 19 8 28 1 10-1 21-4 29-4 9-11 18-18 24a67 67 0 0 1-56 12c-10-2-20-8-27-15-7-6-11-16-15-25-3-9-5-19-4-29 1-9 6-20 12-28s13-14 23-18c9-4 26-6 32-7 6 0 3 1 3 2m-24 0c9-4 21-3 31 0 9 2 20 8 27 14s12 14 16 23c3 9 5 21 4 31a70 70 0 0 1-31 48c-9 4-20 6-30 6-10-1-21-3-30-8a62 62 0 0 1-34-46 67 67 0 0 1 23-53c6-7 20-14 25-16 4-2 0 1 0 2&quot;&#x2F;&gt;&lt;text x=&quot;36&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(36 334)&quot;&gt;user &lt;&#x2F;text&gt;&lt;text x=&quot;36&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(36 334)&quot;&gt;site&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M230 208c11 3 22 10 30 16s15 14 18 22c4 8 4 17 2 26a61 61 0 0 1-39 44 100 100 0 0 1-69 4c-11-3-20-10-28-16s-16-14-19-22-3-19-2-27c2-9 5-17 11-24s17-14 27-18c10-5 20-9 33-9 13-1 35 6 43 8 9 2 7 3 7 3m-42-12a94 94 0 0 1 63 26c7 6 11 14 14 22 2 8 3 19 0 27a72 72 0 0 1-43 40 116 116 0 0 1-71-1c-11-4-22-10-29-17s-11-16-13-25c-2-8-2-18 1-27 3-8 9-15 16-21 8-7 17-15 27-18 10-4 30-5 36-5s0 1 0 2&quot;&#x2F;&gt;&lt;text x=&quot;50&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151 227)&quot;&gt;centurylink&lt;&#x2F;text&gt;&lt;text x=&quot;50&quot; y=&quot;25&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151 227)&quot;&gt;or &lt;&#x2F;text&gt;&lt;text x=&quot;50&quot; y=&quot;50&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;20&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(151 227)&quot;&gt;something&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#ced4da&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M355 328c12 2 25 10 34 17s15 15 20 23c4 8 6 18 5 28-1 9-7 19-14 27s-17 14-28 19c-10 4-25 8-37 8a127 127 0 0 1-72-18c-9-6-16-16-20-24-4-9-5-18-4-27 2-9 6-20 13-27 7-8 17-15 28-19 11-5 22-8 36-9 15 0 42 6 53 8 10 2 11 6 10 6m-15-10c12 3 24 11 32 19 8 7 12 16 15 25s5 20 2 29-10 17-18 24a98 98 0 0 1-68 24c-13 0-27-3-39-7-12-3-23-10-31-17s-15-15-17-23c-3-9-1-20 2-30 3-9 8-19 15-26a141 141 0 0 1 70-23c13 1 32 6 38 7h-2&quot;&#x2F;&gt;&lt;text x=&quot;55&quot; fill=&quot;#ced4da&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(271 353)&quot;&gt;as1299 &lt;&#x2F;text&gt;&lt;text x=&quot;55&quot; y=&quot;35&quot; fill=&quot;#ced4da&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(271 353)&quot;&gt;(arelion)&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#ced4da&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M505 197c14 1 28 5 39 10 12 4 23 11 31 18 7 7 13 16 16 23 2 8 2 17-1 25s-11 16-19 23a138 138 0 0 1-73 25c-14 1-29 2-42 0a161 161 0 0 1-71-29c-7-7-13-14-15-22s-1-17 2-25 10-16 18-23c9-7 20-14 32-18 12-5 25-8 40-9 14-1 40 1 49 2s5 2 5 3m1-1c14 1 29 6 39 12 11 5 19 14 24 21 6 8 11 16 12 24s-1 17-6 25c-4 8-13 15-22 21-10 6-21 11-34 15a175 175 0 0 1-85 3c-14-3-30-7-40-13-11-5-18-12-24-19-6-8-10-17-11-25-2-9-1-19 4-27a138 138 0 0 1 102-41c14 0 33 2 40 3s2 2 2 3&quot;&#x2F;&gt;&lt;text x=&quot;74&quot; fill=&quot;#ced4da&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(407 224)&quot;&gt;as395823&lt;&#x2F;text&gt;&lt;text x=&quot;74&quot; y=&quot;35&quot; fill=&quot;#ced4da&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(407 224)&quot;&gt;(doof)&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M537 342c11-3 27-3 40-2 13 0 27 2 38 6 12 3 23 10 30 16 8 7 13 15 15 22 3 8 4 17 1 24-2 8-8 16-15 22-7 7-17 13-27 17a134 134 0 0 1-77 6c-13-2-26-6-36-11s-17-12-23-19c-5-7-9-16-9-24s4-16 8-23c5-8 12-16 22-22 9-5 29-11 36-13s3 1 3 1m51-1c12 2 25 8 35 13 10 4 20 9 25 17 6 7 8 17 8 25 1 8 0 16-5 23s-14 15-23 21c-10 6-20 11-32 14-12 2-28 3-41 2a135 135 0 0 1-66-23c-8-6-14-14-17-22s-5-16-3-24 9-17 16-23c8-7 19-12 29-16 11-4 22-8 34-9 13-1 35 2 42 3h-1&quot;&#x2F;&gt;&lt;text x=&quot;62&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(507 362)&quot;&gt;as54429&lt;&#x2F;text&gt;&lt;text x=&quot;62&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(507 362)&quot;&gt;(us)&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m100 314 31-24m-31 25 32-24m-11 15c2-3 5-6 10-16m-10 17 10-17m-19 6 19-6m-18 6 18-6&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#ced4da&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m243 306 35 30m-36-29 36 29m-22-7 22 6m-21-7 21 8m-13-19c5 5 8 9 13 18m-12-19 12 20m90-7 29-27m-30 27 30-26m-9 18c2-7 5-13 9-18m-9 17 9-17m-18 8c6-4 12-6 18-8m-18 7 18-7m110 17 8 26m-8-26 8 25m-8-11 8 11m-9-11 9 11m1-14-1 14m0-14v14&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M521 31c11 5 19 16 24 26 6 9 8 18 9 28 0 10-2 23-6 33s-12 18-20 26c-9 7-20 14-32 19a140 140 0 0 1-80 6c-13-3-26-10-36-17s-17-15-23-24c-6-10-13-23-14-33-1-11 5-21 9-31 5-10 10-20 18-28a127 127 0 0 1 73-26c14-1 27-1 42 4 16 5 40 20 50 26 9 7 10 14 8 15m-7-8c9 8 13 19 16 30a62 62 0 0 1-14 61c-8 8-17 14-28 21-11 6-26 13-40 15s-29-2-42-4-25-4-36-10a80 80 0 0 1-44-55 64 64 0 0 1 17-59c7-8 16-18 27-24s25-8 38-9c14-1 29-1 42 1s25 3 36 9c12 6 28 23 33 27s-1-3-2-3&quot;&#x2F;&gt;&lt;text x=&quot;66&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(384 39)&quot;&gt;as6939&lt;&#x2F;text&gt;&lt;text x=&quot;66&quot; y=&quot;35&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(384 39)&quot;&gt;(hurricane&lt;&#x2F;text&gt;&lt;text x=&quot;66&quot; y=&quot;70&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(384 39)&quot;&gt;electric)&lt;&#x2F;text&gt;&lt;g stroke-linecap=&quot;round&quot;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M545 131c8 14 39 49 52 85 12 35 21 106 25 128m-79-211c9 14 40 46 53 81 13 36 21 109 25 131m-14-26 14 26m-14-26c3 7 10 16 14 26&quot;&#x2F;&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-width=&quot;2&quot; d=&quot;M627 315c-3 8-2 18-6 30m6-30c-3 9-3 19-6 30&quot;&#x2F;&gt;&lt;&#x2F;g&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M294 122c8-1 19 2 26 6 8 4 15 11 19 18 4 8 6 18 5 26s-6 17-12 23c-6 5-15 10-23 12-9 3-19 3-28 1a50 50 0 0 1-36-35c-1-8 0-18 4-25 4-8 11-15 19-20 8-4 23-6 29-7 5-1 4 1 4 2m-24 2a55 55 0 0 1 53 9c6 6 11 14 13 22 2 7 1 16-2 24a54 54 0 0 1-44 30c-9 1-18-2-26-6s-16-11-20-18c-5-7-7-16-6-24s6-18 11-24c6-7 18-13 22-15s1 2 2 3&quot;&#x2F;&gt;&lt;text x=&quot;20&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;28&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(275 148)&quot;&gt;???&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;m252 220 16-19m-16 19 16-19m-5 12 5-12m-5 12 5-12m-11 7 11-7m-11 7 11-7m57-71 24-18m-24 18 23-19m-7 13c3-5 6-9 7-13m-7 13 7-13m-13 5 13-5m-13 5 13-5&quot;&#x2F;&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;div&gt;

&lt;p&gt;The &quot;???&quot; network represents hops between a residential ISP&#x27;s network
and HE. In our case on Centurylink and Comcast there&#x27;s a direct
connection&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#level3&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to HE (AS6939), but other ISPs might go through a
transit provider. Also, AS1299 and AS395823 are no longer part of the
traffic&#x27;s path so they&#x27;re grayed out.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, we&#x27;ve discovered a path from other networks back to our
network at the SIX that doesn&#x27;t involve a transit provider. This
traffic doesn&#x27;t cost us anything (because we peer with HE) and it
&lt;em&gt;might not&lt;&#x2F;em&gt; cost HE anything either (because they&#x27;re probably peering
freely with big ISPs).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h2&gt;
&lt;p&gt;With WireGuard as the innermost tunnel, the packets look something
like this mess:&lt;&#x2F;p&gt;
&lt;div class=&quot;svg-figure&quot;&gt;
    &lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 1152 435&quot;&gt;&lt;title&gt;a diagram of user packets tunnelled via Wireguard via Hurricane Electric IPv6 Tunnel Broker via Centurylink PPPoE&lt;&#x2F;title&gt;eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1dW1NcdTAwMWK7sn7Pr6DYXHUwMDBm55yqPbN1v6w3ICFcdOGWcE1O7aKMPYDvxjZcdTAwMThYlf++NVx1MDAwNjwjzdhSXHUwMDAzJiTbWatSwe5m1FJ3f909Lenvd0tLy8PbXrL819JyclOttOq1fmW0&#x2F;M&#x2F;08+ukP6h3O+YrMv550L3qV8eUXHUwMDE3w2Fv8Ne&#x2F;&#x2F;pVxxNVu+54raSXtpDNcdTAwMWNcdTAwMTi6&#x2F;zc&#x2F;Ly39Pf4795x+Ulx1MDAxZFY6561kzDD+KntcdTAwMTRl2P10u9tcdTAwMTk&#x2F;VjElXHUwMDExxVpNXGLqg&#x2F;fmccOkZr49q7RcdTAwMDZJ9k360fJqv7JWu904PTq7XFxZu&#x2F;x6c9ZtVqrZU8&#x2F;qrdbe8LY1XHUwMDFl1aBrJMm+XHUwMDFiXGb73WZyVK9cci9cdTAwMWUnIPf5NK5+9+r8opNcZlx1MDAwNlx1MDAxNk+3V6nWh7fmM4zQ5NP7KfhrKfvkJqXAgk0+SFlcdTAwMTiVMXdcdTAwMWW&#x2F;1m11++nj&#x2F;4GT9L9sXHUwMDAwp5Vq89yMolOb0Fxm+5XOoFfpm0XJ6EaPguHs8Vx1MDAxN0n9&#x2F;GKYTrSItfUne3wynmssXHUwMDA0XHUwMDEzVGmZXHI1fWjvc2287P&#x2F;OZrhfaSefU5bOVauVn6ZO7WGaXHUwMDFl1SNTXHUwMDEw+vDJz0yqlP6Dq1h55bJcdTAwMTRsmNxkoubU4Xg9+XLcxtUjcnlyd7GxwvYjsrs8ofv58K9s+Fe9WmX4ILFWWFGdaiCdfN+qd5qubK1utZkp5LucIFx1MDAwNUOwxpm3XHUwMDAxOtVcdTAwMDZcYlx1MDAxMlx1MDAxY0spSLBccpRcdTAwMGL9tm2AIFx1MDAxMkujZEJiyYmmtkFwNUeDwJTE3DxZcME0w1xmiaJ9MF4wXGIsXGLlhDPxfIOwviho&#x2F;ksqZzaqbme4V79cdTAwMWJcdTAwMWKfsD5dr7TrrfGqTT5cdTAwMWVrrZnGXuW21a3kXHUwMDE2Pv1ipVU&#x2F;T1V4uWpcdTAwMDac9C3tXHUwMDFl1lxyWkxcYtr1Wi1cdTAwMGZcdTAwMDFV87RKvZP0P4e47m6&#x2F;fl7vVFr701x1MDAwNmOkTz49Llx1MDAxOI5cdM9pxCBJv02FJTPtcyZQccrdT1x1MDAxZo1cdTAwMTRrLTVnKptKn5Fer3VuOz++XHUwMDFmjLa3vzTY6NPlzYhtvnEjRTKT71x1MDAxZajmaZcqQ&#x2F;1cZqeYXHUwMDBmpyjHWlx1MDAxMkyzof9cdTAwMGU4dUjPb1x1MDAxMTtcdTAwMWOtSPLlZO2y3vh+drD3XHUwMDA2cUqQqSZAMFx1MDAxMZRwXGawgXKp37hccmhcdTAwMWNrwozqXHUwMDExKpFA3LaIuVwiXHUwMDE1XHUwMDE3MeZcYiFscEdJpcOQylx1MDAxMGPNXHUwMDA1Vs+3iN9cdTAwMDWohtXenEDK47ZdkLJcdTAwMDYyd4BcIlx1MDAwNLmfTjIpQZDxiyzcOPeS7e1cdTAwMDHrRntXPzbJsDnCx3XceNvGqbWbSGnn2S+ITjhG+T+ZcufAqphFSVwipaTyXHUwMDA1bPFcdTAwMTXR6dtp9Fx1MDAwNV&#x2F;yg0uJefLhU5vii87qXHUwMDFiRCeSK1x1MDAxNDj6T7lCXHUwMDE0SVx1MDAxMp5FlVx1MDAwYv2m9d9QoFi+JlwiiXylYla2RFx1MDAxMNZYIPFflC3Ve9dsTijk8c0uXG7ZI5k7XGbR3CS7eZI0KipcZlx1MDAxNlx1MDAwMYLE96e7vd56o9Ho7+1KdrKL3rdv3rZcdTAwMWRKlf38kCfNzVx1MDAwMk2qY6dEXHUwMDE56OSqe649Miy51i9cdTAwMTJcdTAwMTO+XCJcdTAwMGXxjY&#x2F;y4OZsZf94XVxmLnon36W8XHUwMDFlvEFcdTAwMWOiuVx0L2RJiGKlXHUwMDE0XG5cdTAwMDeicqnftFx1MDAwMSjEY1wieZapvFwiJGFBY5bmZ0IzRVhcdTAwMGXxZ+FcdTAwMTMzK8JcdTAwMTl+garB71x1MDAwMk+jej85v6r051XO8&#x2F;htXHUwMDE3o0qG81x1MDAxY6C6N51m9fv3m&#x2F;1ke9Rpk8&#x2F;HvPtcdTAwMDNdNq9z8k5Hs7FcdTAwMWJHytZbKnJ6+6hvskTBclxuXzSQl1L4X2v4c8WLXHUwMDA3qyQmWOAkfStQ4mQx0e6nkyhDXHUwMDE4XHUwMDA3xDRcdTAwMGWK9l9cYpt0beN9&#x2F;yQ6Pz5cdTAwMWZcXNCjjVx1MDAwYvxtu3v0XHUwMDBisGnWaFxuim9cdTAwMDPYWOcxi1x1MDAwNVeUXHUwMDEy4zslkjNcdTAwMWP3pCqlYmFcdTAwMTgoo1x1MDAxY3HFy1x1MDAwMpCcw13Ywyy8mLxcXMJMXG6NXHUwMDE1KVP83Ko4is9ccotgKuhdoav31jheXHUwMDEwnFx1MDAxZfHmqpYrhYFcdTAwMTHr6bBkYcU0sPJcdTAwMDCFXHUwMDBiVpYsXHUwMDA1mJphlzt9XTmILn&#x2F;ojcuv31x1MDAwZprRwfutL8NgQOLMscdSQDJptp1cdTAwMTFkTDmAmla9Wtjn0&#x2F;FKKSm1wZ1CXHUwMDE1Nlx1MDAxZN+sl4eUSsVMpPx6cHV9e9Xo7P6obKmNr8OGWF2tXHUwMDFjjNZ&#x2F;XHUwMDE5XFyVjyZcdTAwMDCuuKazXHUwMDBiXsGFqoXeh+CSxFgjJmWphuOp1VeMiDKMNCjrfW1gqveuxdtFJlx1MDAwZmKUlPrE06Dp&#x2F;da342&#x2F;75PDL4O68ff3pR&#x2F;d6pdlcYoYmxjNcdKZDky6xwVx1MDAwNVx1MDAxND2M6UWhiCNjqpSWQ1x1MDAxMZueOVx1MDAxMVx1MDAwM2BSaZxcdTAwMDXxc4einY1et9c8QtVop3FHt5un7Vx1MDAwZjeNX1x1MDAwNkXlo1x0gFwiJvhcdTAwMDKKXHUwMDFlPn1ccihSTGohMSqrXHJcdTAwMTDKpml4Wlx1MDAxNsTkSfr9XG5AxN4uXHUwMDEwefBcdTAwMDH4zmmGXHUwMDA1XjW&#x2F;ne91WtvN5lx03zjb&#x2F;2Rysv5tMFx1MDAxMFFcdTAwMTZStMOo7DXJomr3XCLQw1x1MDAxNDFcdFxyL0SDKZMsVDQmXHUwMDFkKoRJgp5cdTAwMTQhPlx1MDAxMXjW23hrd&#x2F;Sh0cZtPNrD1ZWj&#x2F;ZMvv1xmeMpHXHUwMDEzXHUwMDAwPJTTmKcvPFx1MDAxZTvSQkBIk1gjVPKCZlx1MDAwMUhPXHUwMDA0JGpCLqowLiBP+l2xkJe9XHUwMDExx0ohJYP2uLw2XCL1er1u8nYhyYNcdTAwMTSFjnFbXHUwMDFhXGImra6J3u5av9Zu3NDT&#x2F;u6qqu&#x2F;fdorGedY3uvC4m2r8zX1kmM3K7dhcdGZrPXmNz0p6OXnG92iCNMZcZnNNXHUwMDA0p1xcaZnbKLEwyYJJXHUwMDEyXHUwMDEz6CnFRbEtLP1STC1XSKY0l7nc6ddbZK9bd7Eu+9dS5pnHP0z+&#x2F;e9&#x2F;llJHOE+OYeRcZkYuYOTSR25cdTAwMGad+MiJRe5cdTAwMWS7Te5cdTAwMWQ7tciVj5zlyYl3mbhF7lx1MDAxNVVY5NRHLmHkylwi5z5ybZF7J1x1MDAxMiMgvaVcdTAwMDbErzXWwlx1MDAxMu9KYXuptJeeXHUwMDAz6a3Zp15VIFxiSE+A9Fx1MDAxY0ZPMZBcdTAwMWU4XHUwMDFlyoD0lnpSr0ujXHUwMDFh9vtcdTAwMTlw&#x2F;IxcdTAwMDLpgfPPgPrDXHUwMDE0jJ5cdTAwMDP1jVx1MDAwM+XlQHmF7Vx1MDAxZrz2JYD2K1x1MDAwNIxeXHUwMDAyxyNcdJBcdTAwMWU6XHUwMDFlXHSk1zB6XHUwMDA1lFdcdTAwMDHnX1x1MDAwMeXVwPFoXGakXHUwMDA3rpdcdTAwMDb6f1xylVx1MDAxN2jv2vZvXn+YXHUwMDBiwUNcdTAwMTlsj+iNrDCiUFx1MDAwNlx1MDAxYlx1MDAwM7whXHUwMDA3RrZTXHRcYjqsVaD+KFx1MDAwMtnL4Fx1MDAwZiOQtVx1MDAwZcy7bthcdTAwMGWEmDfow3YkxPyzZIdCzC+Dw+CPbWxcdTAwMDbu1yWHIWCWnjckuNB+1XBcdTAwMThcdTAwMDJcIljyvIXzXHUwMDFikMPgXHLxXYZcdTAwMDDls2yaXHUwMDA1rDSD2oNt01x1MDAwMVx1MDAwYiegXGa2TVx1MDAwN6y0elx1MDAxZUOAamggg5NcdTAwMWVcdTAwMDQw2PG7X&#x2F;lcYoUyQL23k4JcdTAwMDQw2Cvtt1x1MDAwN6KgXGb2OvhccohcIihcdTAwMDOGMlx1MDAxMChcdTAwMDOFMjAoXHUwMDAzhzJcYiiDhDJAXHUwMDE3jkFcdTAwMTeOQVx1MDAxN45BXHUwMDE3jkGnlUFnyUlcbv3u3snyXHUwMDAyXHUwMDE4XHUwMDE4lEFcdTAwMDBcdTAwMTlcdTAwMDQ0blx1MDAxNVx1MDAxOMrAoVxmXHUwMDEyylx1MDAwMCxeYDubXGZhYFBcdTAwMDao0Fx1MDAxMppwKOjCKahcZlxuKoOCroOGyqChXHUwMDBiZ+eJIVxmUOXTQKFcdFx1MDAwMspAnMQvgFx1MDAwMSg0QUDlI1x1MDAxOLhwXHUwMDA0Q4XGQOUjXHUwMDE4KjRcdTAwMDauNCFQoVx00FVcdTAwMTJcdTAwMDI0UUKgQlx1MDAxM6i2XHUwMDEyqGpQ6CxR6CxRqD1Ai+HEXHSwXHUwMDAyXHUwMDE4oK8j7Hq7v35FKLDg6DJ48zhih3D+V0LEXHUwMDBl4fyvtIhcdTAwMWTC+V&#x2F;IXHUwMDEx+y1cdTAwMDDxrzSzVlx1MDAxYftnyVx1MDAwZVx1MDAxMnGA0DaDN1N0XHUwMDE5XHUwMDAyZslm8L9ydVx1MDAxOLxxq8tcdTAwMTCwXHUwMDBlNkPAOthcZn57mM7wzmFcXO71k8HgyvxltzhcZurtq1ZlmOw+fG2+XHUwMDFk9q+yXHUwMDA2gFZlMFxc67bb9eEwqe2m3Vx1MDAwMFYzgDWCyfPvn&#x2F;7z&#x2F;pu&#x2F;XHUwMDFmf9V9S8v307Nvoz1+ez6oyUNGVoQ+2rxcbm1poVLHWpqMWlx1MDAxM6mMrdpcci5cZvNYUYqQlFQgnu0&#x2F;m2xcdTAwMTkt2TMtit2XPNaMXGIuXHUwMDA1libW4lmp81x1MDAwZmx2mSze8vnR7kGzeVT7tvN5rX483L+7XHUwMDFi7pPlglx1MDAxZT29b5pwTmhub3Rua2lxv8CkT41cdG7+z+&#x2F;F&#x2F;sO6Yiw4iPypp+Wro1x1MDAwMFfqPMDrSu3CSuSvx9qYXHUwMDE5+cvcttuKuFx1MDAxNz&#x2F;sXHUwMDFhQySAL54j4fW99pvnSHhnidvTKrzrwInN4J0ll8FcdTAwMGLLM1x1MDAxOF5cdFx1MDAwZfIjyJ4&#x2F;XHUwMDBiXHUwMDBlblx1MDAwNoefrr+K6uijXHUwMDFhttrseJ81P35cboZcdTAwMDPFY8k4Nb6ecUWzKs5cdTAwMDNcdTAwMWOI2ES9XHUwMDA0U04xY7jY&#x2F;Vh2JHmWTCzwYI54QIVMXHUwMDBmsS6eWDRcdTAwMWXb9I1iVGGpXHUwMDE1&#x2F;XPhwPZDfjiwyP3FV9tTe7HDdiher2uR+&#x2F;2VjWReXHUwMDFmLWx6WGdi5M8hbJDxI6tccnv+tMmm9+dl2NFcdTAwMDW&#x2F;MjhcZlx1MDAwMc1cdTAwMGVTXHUwMDE5Xlx0MfIjyJ4&#x2F;XHUwMDBiMZDe2ddcdNrcXFxlqL623&#x2F;jRuGiQYMTQJJbKYEG6oVxcSY2dky0wjSVhXG5rgrSWNHvRPMFcZlqSQ1x1MDAxNPdcdTAwMGUvIGNcdTAwMGUpRFxu41SS0q0uuZ6A4k1cdTAwMTaaUYQ1f0ubL+eXQsCo&#x2F;UVcdFx1MDAxMDVcdTAwMDVRXHUwMDBiXHUwMDEwtVx1MDAwNFFj4Fx1MDAxNDpplZeew+jtKnhcdTAwMDA9XHUwMDA20lMgvVx1MDAwNNIrIL1cdTAwMDN2XsVcdTAwMDGmwXZDwnPoX1x06PJcdTAwMDOYPH5cdTAwMTbONe92Vf&#x2F;bOVx1MDAxNcd7ndWdjc5pb3u7WsS5ko2ZxM6DiC7uw8RaxjQ9019gRDnmolx1MDAwNNVcdTAwMTY7MWH4pJTkjDBdXHUwMDA2T9lL4eJcdTAwMTk1aVwiRFju5pBfj06TXHUwMDBiXHKSVrW7VO1fneWX7MnbMVvJmX1wrb1cdTAwMTlz2O3lXHUwMDE1yL9cdTAwMTPTXHUwMDEypXBcdTAwMDdC2dghmy&#x2F;F&#x2F;mirXHUwMDE14Vx1MDAxMX1P2&#x2F;uDzUq&#x2F;0ezjoNOhsoaV+42XuWMhJuf4i5imm6dcdTAwMTWT6blcdTAwMTDZhC3M78mHRHFigkNeemqnLnyYnYImkED6SYegzdv8xLD7XCInc7yq3dmDXHUwMDA2XHUwMDE53IEkV5u7&#x2F;fftteujj&#x2F;v1o91delx1MDAxZbzbWdmpXHUwMDFjz41+gnolVzvlpnJhZiFmxrikgklaes7G1PNvTMbN0oNF6Vuys5fd3Wy&#x2F;pveSW1x0h3+7skXufXdcdTAwMTBZ4bq&#x2F;lFx1MDAxNWFgk0HkbFX1j1xiXHUwMDAzeywjaP+6+4TnMLxzXHUwMDE455RcdTAwMTRYI5g8f1ZWsKOPbkSiRvxcdTAwMDM+k5XNndN1cVx1MDAxZIX7SPtEfJ5zflx1MDAxM1x1MDAxZlmSXHSQhY9cdTAwMDRWqjDDXHUwMDFhXHUwMDEzUfaye&#x2F;qVq1x1MDAxOGmkXHUwMDE5ybXN&#x2F;mk+kj2dXHUwMDFhVu332r5F7XVetjdcdTAwMDWW1f1cdTAwMDc0OMdcdTAwMTD46&#x2F;y2s1x1MDAwZdhRYtFcdTAwMDfs05lG&#x2F;0p+MT9cdTAwMDBcdTAwMTLiXHUwMDE2+99cdTAwMGV3259vXHUwMDBlaqfH31x1MDAwZmrnq1xun1x1MDAwZlx1MDAwZoPdonTdYsmr4lx1MDAxMreI6dQ7cFx1MDAxNm4yxE1qprjCqLQnaPoxOUSaXHUwMDFjz0DZb1x1MDAxNEk+w+9cdTAwMTlcdTAwMTVjXHUwMDE4S1x1MDAxM3EjrsYn3MGcXHUwMDE1jlV6YfTkl3grt1x1MDAxNjujcZ45oFMnzy1ZrPJP9zoqy1x1MDAwZmpcdTAwMTXnXHUwMDFmrfwnXHUwMDAw2W2sWMWW5MCQvGjdL8f&#x2F;Sm40P6BJv9EsN3p+OVx1MDAxYcottj48wVfdreZqi3&#x2F;4kISUvFx1MDAxODGLpTjFgppcdTAwMTSPSLtcdTAwMDBmzDVcdTAwMTYmsNFUSYpcdTAwMTgv1qNcdTAwMTlcdTAwMTGxMT06vjOW5jZlLuphT&#x2F;WuXHUwMDAya00pKz0zfUY5zGTpnEtO51x1MDAxMIOmf7JFfEI9rJZcZoZ&#x2F;LX368D+DpeFVp5O0lk7Tqe&#x2F;&#x2F;djUyvyCQulmlvy5cIr2xc7GSrN983Ti62Dm7qoVcdTAwMDY&#x2F;3GmiLqublZTN8Fwi1oGdXHSolaZElp9cYjjNXHUwMDE4XHUwMDA1Slx1MDAwZqelQVebv5FI51x1MDAxOc1ufny2z4mAwbG&#x2F;QGV3I&#x2F;hHXHUwMDAzTFxup9O&#x2F;VjSQXHUwMDFiXHUwMDAwXHUwMDBl6bS6a41GlFWvuse1k0azpjc+XHUwMDFjXHUwMDFml9xcdTAwMWE0za&#x2F;YMVx1MDAwMM+94MyuXGYqOpZFrVx0mkShNFx1MDAxYlwipUlcdTAwMTSZmkRJgrSiVL+lt84v6lpcYojaPlx1MDAxZsZHbVuyv7fILlx1MDAwN&#x2F;nLNcBcdTAwMDM7XHUwMDFkev&#x2F;vt09cdTAwMDHzl4Om0r+S58pcdTAwMGYgqFx1MDAxY3SxS9dOXHUwMDA3jY6+OdtcdTAwMWag7ubaXHUwMDE2v1x1MDAwYj43ueC5WNFzlTiubJvmwnEthUREXGJjXCKJ1mVcdMp0x8WEJml77lu60ulcdTAwMTfGRFx1MDAxNrXXkm1HXHUwMDA0fKXpr2NH0HeC0Fx1MDAxN3ZcdTAwMTa9f2PadPpXclxc+Vx1MDAwMbCQpr&#x2F;19zcnm1x1MDAxZipcdTAwMWZ3hp&#x2F;1+t7Op&#x2F;NcdTAwMWFaXHUwMDBmu5FcdTAwMGXz2Fx1MDAwMDoz6ZxQlDO7XHUwMDA1kKviiz6OcKzyLYAlLm1Rclx1MDAwMb73k5jy9Fx1MDAxZF6JSyv2XHUwMDA1ZjWXdCeUVPN476dlvjP+yTWX7lV&#x2F;aXJV9lLSqY1d3m9ad&#x2F;FcdFx1MDAwM6m9fLxcdTAwMWX1XHUwMDBmfvCv0ernr3drtZXL5spNLzTSwIjjmDNjtoRcdTAwMGLOc9WB+7ijWImR8fiCZCw4JlRl5zbkXG4zSMVKYqNRgkmmhCxe5rCw4VlcdTAwMWJcdTAwMTNcdTAwMTU2XHUwMDEzy8s3mYhCrDIp1UgtmUbzKNWkXHUwMDE3WKq8cr5QWIJjwYxcdTAwMTZxZZTPRFSwhIlPUcT0XHUwMDBmi1x1MDAwNULE4IpcdTAwMTZUXHUwMDEyIf07nWf8MkxjlWKU4kpjrJD&#x2F;&#x2F;MRZv43oXHUwMDE4UyaoJoxcbk1FwFx1MDAxMf4zZomJXHUwMDE4JqhcdTAwMWRQSVx1MDAxNVx1MDAxM5TeXk6pScU5XHUwMDA3XHUwMDE2wDSPkUSaKMRcdTAwMTVcdTAwMTXKv6HcXHTnXHUwMDEwi4nBK4aMtmPMkHfzqMvvOpqX43+t8Cw3IFx1MDAxY1x1MDAxNJ9VOndr+nR&#x2F;q3PGL1f2No&#x2F;WjmWXh7t75jRcdTAwMWGwYmN4WU0st0994cNDUkujzVx1MDAxMitSflxy6fStXHUwMDE4jFx1MDAxOJcr2Ju6x&#x2F;5le1RhLVV2yTrgXHUwMDA2XHUwMDFly8ChLaFcdTAwMDH56HSG1&#x2F;JcdTAwMTj5XHUwMDExXHUwMDA0nXe0tb23drK7sq1cdTAwMWF9+mVcdTAwMTOvXa7I05JtXFxTXHUwMDAzRPtWvbJaVGnH5sJjQFuRsFScXHUwMDE0L8ybWYxKrzFkWopFNeqBIE9ccjsuwustgK&#x2F;n5t2yabdI+mv0U+lfyXNZLZUhjuukebTzsTnEODnm9WF0e&#x2F;Dj6HPJfbjFUpSWPMbC5EpcdTAwMDQxpPNZ7LhcdTAwMTeIo9jALKVCUqZJMVx1MDAwMKLahNwmXHUwMDFlxlx1MDAxYWkstVjcXHUwMDEx+lx1MDAwMlvjKCNKsmKnwTjqke6nk7txtclcZqSax0tCo1x1MDAwMOhcdTAwMDV6gXpJf+lqYP4yS3h2Vq&#x2F;+plx1MDAxNanpYkBqUT3Vfz9I1N7t6fVcdTAwMTFqN3DvsD8qucq3PNSQxH7rxUhJpFFWJOaLUFx1MDAwM1x1MDAxOGpgk3VcdTAwMTNSaoxq6ikm6eXxVMu5VJjeRqhcdTAwMDHdQFx1MDAwNzxcdTAwMDHCofdnMzY9sLpcdTAwMTJB365cdTAwMDWcZ+UywNqpXHUwMDAz6J3fXHUwMDBmPO&#x2F;LXHUwMDFmNFx0IL1cdTAwMDLSu8dZXHUwMDAxo7JcdTAwMTBcdTAwMDZcdTAwMDZlXHUwMDEwQFx1MDAwNlx1MDAwMpWBQGUgUFx1MDAxOZyzX&#x2F;xcZlx1MDAxNCpcdTAwMDOFXHUwMDBliUJVg1x1MDAxMShcdTAwMDNUWVx1MDAxOXRIXHUwMDFjOiRcdTAwMGVcdTAwMWSSQFBcdTAwMDbokFx1MDAwNNhcdTAwMDWAZYBOq4TKIKEySOiQXHUwMDE0dEhcbjpLXHUwMDFhKoNzkWJcYlx1MDAwN4Zqk3MpWlx1MDAxMFx1MDAwN9jlu1x1MDAwN2tcdTAwMDVwgCUn4NklYMndXHUwMDAztvxcdTAwMWNcdTAwMTQsOVx1MDAwNctBofCFKVx1MDAxNCycS7BCjrl0nHlcYodcdTAwMDMwXHUwMDAxPZiO5P4uSVx1MDAwN1x1MDAwMEJu+7Y5&#x2F;Fx1MDAxN2Bg55jqgMvkXFxcdTAwMGW&#x2F;XHUwMDFjLodfXHUwMDBlXHUwMDA3yVx1MDAwMm5wdDlcdTAwMDLkcDhcdTAwMDLksNc84PbNXHUwMDE5XHUwMDFj71x1MDAxY855VenyQ8hcdTAwMDYwq05cdTAwMTd9XHUwMDFjXHUwMDFkNsngZLB13qqcND7XXHUwMDBmVuonoVm&#x2F;yf8mP99n&#x2F;SWn5qCSNpNF1lx1MDAwZsz6Tb5vXHUwMDEy+Nzdv7msP1x1MDAwYlmKR0JgXCJcdTAwMTFiufdcdTAwMTJ&#x2F;WNZcdTAwMGY879omXHUwMDA3ZsCw&#x2F;lh&#x2F;yu9cdTAwMDAwOONcdTAwMDe+r1xyKVx1MDAxMThcZv4qh4AyOHFKwCk70DjFeY9cdTAwMWPEXHUwMDAxjbdcInCkXHUwMDE5gePGXGJcdTAwMWM3RuC4MVx1MDAwMseNXHUwMDExOG6MKFhycKRcdTAwMTlRsOTgXHUwMDFhQMTAkoPLXHUwMDA2XHUwMDExXHUwMDAzS1x1MDAwZa40ROBSQ8TBkoOrXHUwMDEzXHUwMDExXHUwMDA3j1xuXFyfiMBcdTAwMDWKXGJcXKGIwCWKXGJcXKOIJFhycFkjXHUwMDAy1zVcIlx0llx1MDAxY1xcXG6JXHUwMDE0tDZcdTAwMTgpaIEzUtByYuRcdTAwMTRcXFx1MDAwMs6&#x2F;U1xuyqFcdTAwMWTJ&#x2F;VDrcvixVlx1MDAxMzCHM1f+XHUwMDE1tC+HXHLIWiPt5LlcdTAwMDFz5XBcdTAwMDT0niFooltkXHSIXHUwMDFhXHUwMDFjXHUwMDE2XHUwMDE20LOGoNlxkSVEfGh+XHUwMDFj5fK6J7OEzJjNwkNmbDrLO4d1bn1++TFkI5iViCtNmvj04jC6vdzVa1u717x5vVx1MDAxOdIwI7TdXHUwMDE2TEuuqlwiWsVcdTAwMDJcdTAwMGIhTNaG00tFJlx1MDAxNIuumCd3xZjUmlwiXnpg+&#x2F;SdXHUwMDFlSqebtfCbOn7ssSkm29V0kVRqv+HBONNcdTAwMDVcdTAwMDBcdTAwMWQkvS02uu3r5KC6J1x1MDAwNpsnV5s721x1MDAxYsGXylx1MDAxOX1za2LFTlx1MDAxOFJ6dVxcplx1MDAxMlx1MDAwYlx1MDAwM1xmMMDU9jiXpbslZ1x1MDAxY&#x2F;+HqZZMMfZf0lxiXHUwMDAzrSpBXHUwMDFiW&#x2F;yoP+9GXHUwMDE4aFx1MDAxOVxy2jdcdTAwMDMtokFLYlxuSO9cdTAwMTbEwFxmwFx1MDAwM1xcQ1x1MDAxOKC3yrpcdTAwMDU3P1x1MDAwM7RuXGIut4GrbeBiXHUwMDFiuNZcdTAwMDYutYErbeCyXHUwMDE5uFx1MDAwNlx1MDAwNi5ogetZ4OJcdTAwMTS8c1x1MDAwNipcdTAwMDO4llx1MDAwNe+cXHUwMDAxN5FAZ0lBn1x1MDAwMG5cItHgNlx1MDAxNXhHXHUwMDFmuFlcdTAwMDPBm07g7Vx1MDAxZOBRuYbt95euZVx1MDAwN&#x2F;hwMEy4tlxyfqlcdTAwMWWAXW6RN4BcdTAwMDNcbsDYLY5cdTAwMDZwgEHbbeJcbuBcdTAwMDDPlWuyflx1MDAwZVxy1ivXyv1AjKAlW+JYrb84SpySz1x1MDAxMzj83c1cYtrSQ1x1MDAxMLSlZ1x1MDAxNsc7h3NOpStrXGLZXHUwMDAwZlWuPlx1MDAxZpBEvP92KL7sqfVcdTAwMWKxc9n9dNRcbs6XXHS296jSTCdzu9pLekhcdTAwMTZXL0GvXlwiUlx1MDAxM0XLz8ufvnNEKk1cdTAwMTnT5I9NmJ+xSVx1MDAxNbYnXHUwMDAytiNinlx1MDAxYmCB22W9U&#x2F;i8Iy2BXHUwMDFiLfwpuFx1MDAxZJJcdTAwMDXQXHUwMDAzd1x1MDAwN9vZqJ+eXHUwMDAwx0+A4yHA8diJZVx1MDAwMD1w&#x2F;Fx1MDAxNDh+XG5cdTAwMWM&#x2F;XHUwMDAzjp9cdTAwMDH1gVx1MDAwMcfPgfPDgfJcbuB4JFBeXHUwMDA1pNdAeTX090PtXHUwMDExXHUwMDAxXHUwMDE1wklcZkNcdTAwMTiAS4bBPlx1MDAwYupUnL1cdTAwMGIhXGZQt1xi9UNcdTAwMTjqiDDUXHUwMDEzOXltyGnIXHUwMDA0yGDXk0JcdTAwMThcdTAwMTiUXHUwMDAxKoPjL6BZc1xiXHUwMDAz8KxWbDdGgVx1MDAxOUK2PtpcZlx1MDAwMSBcdTAwMGU+yNpmXGKoWtt3K0Fl8HeuuFxm4CH9itO1cyNcYrqEsom1Uud3X798PDyg3YpqdDfkTkinXHUwMDAzRtS+pZeW3EDJXGKKVXpXXGZVWrDSQy5cdTAwMTetXHUwMDBlsMxRmsSRKl56XHUwMDFmpZx6&#x2F;Fx1MDAwN1x1MDAxNlJcYoTe1v0jj61cdTAwMGXj4zLMzDWT4dL&#x2F;Jp1q&#x2F;7ZnnvB&#x2F;v13Hg1eOKY1cdTAwMGbvXHUwMDFlXHUwMDFjw3Kl19tcdTAwMWKa2TXf3pvp8nU9XHUwMDE5rVx1MDAxNpX8XHUwMDFmZ+M&#x2F;y+9cdTAwMWXMOlXwsSv5++e7n&#x2F;9cdTAwMDHV+b4tIn0=&lt;defs&gt;&lt;style&gt;@font-face{font-family:&amp;quot;Virgil&amp;quot;;src:url(&#x2F;fonts&#x2F;Virgil.woff2)}&lt;&#x2F;style&gt;&lt;&#x2F;defs&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M870 153c55 2 111-4 166 0m-166 0c62 2 129 2 166 0m0 0c12-1 19 10 22 21m-22-21c14 3 23 7 22 21m0 0c-4 10 3 23 0 44m0-44v44m0 0c1 15-4 25-22 22m22-22c-3 14-3 20-22 22m0 0c-67-5-131 2-166 0m166 0c-48-5-95-2-166 0m0 0c-17 2-26-7-22-22m22 22c-18-4-20-4-22-22m0 0c-1-12 3-27 0-44m0 44v-44m0 0c-1-15 11-19 22-21m-22 21c0-13 9-19 22-21&quot;&#x2F;&gt;&lt;text x=&quot;66&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(887 174)&quot;&gt;payload&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M781 154c13 4 28-1 46 0m-46 0c15 0 32-2 46 0m0 0c13-1 19 8 21 21m-21-21c12 2 24 10 21 21m0 0v42m0-42c-2 16-1 34 0 42m0 0c1 17-9 21-21 22m21-22c3 10-10 25-21 22m0 0c-14 2-22 2-46 0m46 0h-46m0 0c-14 3-25-9-21-22m21 22c-10 3-24-11-21-22m0 0c-2-15 3-30 0-42m0 42v-42m0 0c-4-18 9-22 21-21m-21 21c-1-12 5-19 21-21&quot;&#x2F;&gt;&lt;text x=&quot;28&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(776 174)&quot;&gt;tcp&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M698 154h41m-41 0h41m0 0c17 1 18 6 20 20m-20-20c11-1 19 6 20 20m0 0c-4 12 0 22 0 44m0-44v44m0 0c-1 17-10 23-20 20m20-20c2 18-2 17-20 20m0 0c-14 1-31 2-41 0m41 0c-15 0-27-2-41 0m0 0c-10-2-20-7-20-20m20 20c-17 1-17-3-20-20m0 0c0-7-3-20 0-44m0 44v-44m0 0c-4-12 8-19 20-20m-20 20c4-15 3-18 20-20&quot;&#x2F;&gt;&lt;text x=&quot;34&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(685 174)&quot;&gt;ipv4&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M486 153c57 3 120 1 171 0m-171 0h171m0 0c12-4 17 9 21 22m-21-22c13 2 24 8 21 22m0 0c-2 13 3 22 0 43m0-43v43m0 0c3 16-7 18-21 21m21-21c-2 11-5 25-21 21m0 0c-67 2-136 2-171 0m171 0H486m0 0c-16 1-19-10-22-21m22 21c-19 4-19-12-22-21m0 0c1-15 3-23 0-43m0 43c-2-14-2-27 0-43m0 0c-3-14 10-24 22-22m-22 22c-1-19 9-23 22-22&quot;&#x2F;&gt;&lt;text x=&quot;82&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(489 174)&quot;&gt;wireguard&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M410 152c9-4 26 0 36 0m-36 0c10-2 21-2 36 0m0 0c11 3 19 7 18 18m-18-18c9 3 20 6 18 18m0 0c2 16 2 39 0 53m0-53c-2 15-1 29 0 53m0 0c3 13-5 15-18 18m18-18c-3 12-9 15-18 18m0 0c-17 3-26-1-36 0m36 0h-36m0 0c-8 0-19-9-18-18m18 18c-12 1-21-7-18-18m0 0c-1-10-4-24 0-53m0 53c3-20 1-37 0-53m0 0c3-9 8-17 18-18m-18 18c2-13 3-16 18-18&quot;&#x2F;&gt;&lt;text x=&quot;29&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(399 174)&quot;&gt;udp&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M253 152c41-2 86 3 117 0m-117 0c46-2 91-4 117 0m0 0c13-4 21 5 22 22m-22-22c12 0 20 5 22 22m0 0v44m0-44v44m0 0c2 16-9 26-22 23m22-23c0 19-7 26-22 23m0 0c-28 2-61 0-117 0m117 0H253m0 0c-13-1-19-10-22-23m22 23c-12 3-24-7-22-23m0 0c1-16-3-31 0-44m0 44v-44m0 0c1-12 9-19 22-22m-22 22c3-17 4-21 22-22&quot;&#x2F;&gt;&lt;text x=&quot;34&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(278 174)&quot;&gt;ipv6&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M158 152c16-2 34 4 51 0m-51 0h51m0 0c15-3 25 11 22 22m-22-22c15-1 20 9 22 22m0 0c4 14 3 27 0 44m0-44c-1 10-2 24 0 44m0 0c-1 18-6 20-22 23m22-23c2 14-11 18-22 23m0 0c-13-1-27 2-51 0m51 0c-18-3-37-1-51 0m0 0c-12-3-23-10-22-23m22 23c-11 1-20-6-22-23m0 0c3-10-1-16 0-44m0 44v-44m0 0c-2-17 10-23 22-22m-22 22c1-13 8-24 22-22&quot;&#x2F;&gt;&lt;text x=&quot;34&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(150 174)&quot;&gt;ipv4&lt;&#x2F;text&gt;&lt;path fill=&quot;none&quot; stroke=&quot;#1e1e1e&quot; stroke-linecap=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M54 152c13-3 31 1 60 0m-60 0c19-1 35-3 60 0m0 0c13 2 22 3 22 22m-22-22c11 4 26 8 22 22m0 0v44m0-44v44m0 0c2 13-8 23-22 23m22-23c2 17-10 26-22 23m0 0c-14 2-31-4-60 0m60 0c-12-1-26 2-60 0m0 0c-16 3-19-10-22-23m22 23c-17-2-24-7-22-23m0 0c2-11 2-21 0-44m0 44v-44m0 0c-3-14 9-22 22-22m-22 22c-4-11 6-27 22-22&quot;&#x2F;&gt;&lt;text x=&quot;47&quot; fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; text-anchor=&quot;middle&quot; transform=&quot;translate(38 174)&quot;&gt;pppoe&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;M384 143v-2l-1-4-1-5-2-4-3-4-4-2-5-1h-9l-5-1h-4l-5 1h-13l-7 1h-28l-6-1-5-3-5-3-5-5-3-6-2-6-1-3v-3l1-1 1-2 1-1 2-1h3l2 1h1l1 2 1 1 1 2v9q-1 4-4 7l-4 4-5 2-5 2-5 1h-5l-5 1h-14l-4 1h-71l-4 1q-3 0-4 2l-2 5-1 4v3l-1 2-1 2-2 2h-5l-2-1-2-1-1-2v-5l1-2 2-2 2-1h4l2 1 2 2 1 2v5l-1 2-2 1-2 1h-5l-2-2-1-2-1-2v-4l1-6q0-3 2-5l3-6 3-4q2-2 5-2l5-2h71l5-1h5l6-1 5-1h15q3 0 5-2l2-4v-5l1-1 1-2 1-1 2-1h3l2 1h1l1 2 1 1 1 2v2l1 3 3 4 5 4 6 2h29l5-1h36l5 1 6 2 4 3 3 4 3 4 2 5 1 6 1 5 1 6-1 2v2l-1 1h-1l-1 1h-4l-1-1-1-1-1-1v-3Zm-311-7 3-6 4-11 5-13 5-14 4-11 2-8 1-7 1-8 1-4v-1l1-1 1-1h4l1 1 1 2v4l-1 1h-2l-1 1-1-1h-2l-1-1v-4l1-2 1-1h4l1 1 1 1v6l-3 8-2 7-3 9-3 11-4 14-5 14-4 11-2 6-1 1-1 1h-1l-1 1h-1l-1-1-1-1-1-1v-3Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;M69 132v-10l1-6-1-6v-4l1-2 1-2 1-1 2-1h4l2 2 1 1 1 2v2l-1 2-1 2-2 1h-6l-1-2-1-1-1-2v-2l1-2 1-2 2-1h4l2 1 2 2v1l1 1v3l-1 6v6l-1 6-1 4v4l-1 1v1l-1 1h-2l-1 1-1-1h-1l-1-1-1-1-1-1v-2Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m77 129 2-1 4-2 6-3 5-2 4-2 5-2 3-2h2l2 1 1 1 2 1v2l1 2-1 2-1 2-2 1-2 1h-2l-2-1-1-1-1-2-1-2v-2l1-2 1-1 2-1 2-1h2l2 1 1 2 1 2 1 2-1 2-1 1-1 2h-1l-1 1-4 1-6 3-5 2-5 2-4 2-4 1h-5l-1-1-1-1-1-1v-5l1-1h1l1-1h1Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(10 10)&quot;&gt;telco cruft&lt;&#x2F;text&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(237 49)&quot;&gt;6to4&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m175 249-1 2-3 6-4 6-3 6-2 6-2 4-1 3 1 1-1 2v1l-1 1-2 1h-1l-2-1h-1l-1-2-1-1v-2l1-1 1-1 1-1 1-1h2l1 1 2 1v1l1 2v1l-1 2-1 1h-1l-2 1h-1l-2-1-1-1-1-2v-3l1-5 3-5 3-6 3-6 3-6 3-6 1-3h1l1-1h1l1-1h1l1 1h1l1 1v1l1 1v1l-1 2Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m177 247 1 2 3 4 3 4 2 5 1 4 2 6 2 4v2l-1 2-1 1-2 1-2 1h-2l-1-1-2-2v-1l-1-2 1-2v-2l2-1 2-1h1l2 1 2 1 1 1 1 2v2l-1 1-1 2-1 1-2 1h-2l-2-1-1-1-1-2-1-1v-1l-1-5-2-6-2-5-3-5-2-2-1-1v-4l1-1v-1h1l1-1h4l1 1h1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m170 252 1 3q2 4 2 15 1 11-1 24l-2 27-4 23-2 21-2 15v8h-1v1l-1 1h-2l-1-1-1-1v-2l1-1h1v-1h1l1 1h1v1h1v1l-1 1v1h-1l-1 1h-1v-1h-1v-1l-1-1 1-7 1-16 3-20 3-24 2-26 1-23-2-14-1-3v-3h1v-1h4l1 1v1Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(113 380)&quot;&gt;dest: HE&amp;apos;s tunnel broker&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m279 249-1 2-2 5-3 5-2 4-2 1h-4l-2-1-1-2v-3l1-2 1-1 1-1h3l2 1 1 1 1 1v4l-1 1-1 1-2 1h-3l-1-1-1-1-1-2v-3l1-1 1-2 3-5 2-4 2-3 1-1h1l1-1h2l1 1h1l1 1v1l1 1v3h-1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m281 242 2 3 4 5 3 6 3 5 3 5 2 3v3l-1 2-1 1-2 1h-3l-1-1-1-1-1-2v-1l1-2v-1l2-1 1-1h2l1 1 1 1 1 1 1 1v2l-1 1-1 2h-1l-2 1h-1l-2-1-1-1v-1l-2-5-4-7-4-5-3-5-3-4v-1l-1-1v-1l1-1v-1l1-1h1l1-1h1l1 1h1l1 1h1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;M281 255v10l-2 8-2 8-2 8v9l-1 1-1 1-1 1h-2l-1-1-1-1-1-1v-2l1-1 1-1 1-1h1l2 1h1v1l1 1v2l-1 1v1h-1l-2 1h-1l-1-1-1-1-1-1v-1l1-3 1-6 1-8 1-9 1-7 1-6v-4l1-1v-1l1-1h4l1 1v1l1 1v1Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(200 301)&quot;&gt;dest: our wireguard endpoint&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;M741 256v4l2 11-1 14-2 20-2 22-1 17v22l-1 1v1l-1 1h-2l-1-1h-1v-1l-1-1 1-1v-1l1-1h3l1 1 1 1v1l-1 1v1l-1 1h-3l-1-1v-2h-1l1-3v-19l1-17 2-23 2-19 1-13-2-10-1-5v-2l1-1h4l1 1v1h1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m735 263-3 2-6 4-5 3-2 1h-4l-1-1-1-2v-2l1-2 1-1h4l1 1 1 1v4l-1 1-1 1h-4l-1-1-1-1v-4l1-1 1-1 2-1 4-2 6-4 4-3h4l1 1 1 1v5h-1l-1 1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m744 253 1 2 2 4 3 6 4 5 2 2v6l-1 1-2 1h-5l-1-1-1-2-1-2 1-1v-2l2-1 1-1 2-1 2 1 1 1 2 1v2l1 1-1 2-1 2-1 1h-5l-2-1v-1l-3-4-4-6-2-4-2-4-2-3v-4l1-1 1-1h1l1-1h2l1 1h1l1 1 1 1Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(659 365)&quot;&gt;dest: per user traffic&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m402 136-1-2-1-5v-6l1-4 3-3 3-3 6-2 6-2 5-1h12l5 1 6 1h39l7 1h7l7 1h20l5-1 7-1 5-2 3-2 3-4 1-6 3-8 2-5 2-2h2l2-1 2 1 2 1 1 2 1 2v2l-1 2-1 2-2 1-2 1h-2l-2-1-2-2-1-1-1-3 1-2v-2l2-1 2-1 2-1 2 1 2 1 1 1 1 2 1 2-1 2v1l-1 1-1 4-1 5-2 6-3 5-3 4-5 3-5 2-6 2-8 1-5-1h-20l-7 1h-7l-7 1h-26l-7-1h-10l-5-1h-11l-5-1-7 2q-4 1-4 4l1 4v6l-1 1v1l-2 1h-4l-1-1-1-1-1-1v-1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;M660 137v-2q0-3-2-5-1-3-4-4l-5-1h-6l-5 1h-47l-5-1-6-2-6-2-4-3-4-5-4-4-2-4-2-6-2-5-2-4v-6l2-2 1-1 2-1h5l2 2 1 2 1 2v2l-1 2-1 2-2 1-2 1h-2l-3-1-1-1-2-2v-5l1-2 2-2 2-1h4l2 1 2 2 1 2v1h-1l1 4 3 5 2 4 2 4 5 5 6 3 6 1h46l5 1h11l6 3 6 5 3 7 1 7v4l-1 1-1 1-1 1h-4l-1-1-1-1-1-1v-2Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(383 33)&quot;&gt;wireguard header&lt;&#x2F;text&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m680 136-1-2-1-5 1-4 4-5 5-3 4-2q2-2 5-2l6-1 6-1 4-1h32l9 1 9 1h35l8 1 8 1h10l6 1 7 1h30l6-1 6-3 4-4 4-3 2-3 2-1h4l2 1 1 2 1 1v2l-1 2-1 2-1 1-2 1h-2l-2-1-1-1-1-1-1-2v-2l1-2 1-1 2-1 1-1h2l2 1 2 1 1 2v4l-1 1-1 1-2 2-5 4-4 3-6 3-7 2-6 1h-6l-6-1h-19l-7-1h-6l-4-1h-6l-7-1h-43l-9 1-7 1h-44l-7 1-5 3q-2 1-1 3v6l-1 1v1l-2 1h-4l-1-1-1-1-1-1v-1Z&quot;&#x2F;&gt;&lt;path fill=&quot;#1e1e1e&quot; d=&quot;m903 104 2 2 2 4q2 3 5 3h10l5-1h17l6 1h14l8 1 9 1h6l6-1h24l6-1 6 1 6 1h17l7 2 7 4q2 2 2 5l1 6v14l-2 2-1 1h-6l-2-2-1-2v-4l1-2 1-1 2-1h4l2 1 1 1 1 2v4l-1 2-2 1-2 1h-4l-1-1-2-2v-2l-1-1 1-3v-6l-1-5q-1-2-4-2l-6-1h-13l-5-1h-5l-6-1h-24l-6-1h-6l-9 1-8 1h-14l-5 1h-15l-5-1h-12l-6-2q-4-1-5-3l-3-4-3-4-2-3v-5l1-1h1l1-1h4l1 1 1 1Z&quot;&#x2F;&gt;&lt;text fill=&quot;#1e1e1e&quot; dominant-baseline=&quot;text-before-edge&quot; font-family=&quot;Virgil&quot; font-size=&quot;36&quot; style=&quot;white-space:pre&quot; transform=&quot;translate(721 51)&quot;&gt;user packet (encrypted)&lt;&#x2F;text&gt;&lt;&#x2F;svg&gt;

&lt;&#x2F;div&gt;

&lt;p&gt;Surprisingly, this gross hack only increases overhead by &lt;strong&gt;100 bytes&lt;&#x2F;strong&gt;
(okay, that is a lot, but I was expecting more). Here&#x27;s the breakdown:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The 6to4 tunnel contributes 60 bytes of overhead from a 20-byte IPv4
and a 40-byte IPv6 header.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lists.zx2c4.com&#x2F;pipermail&#x2F;wireguard&#x2F;2017-December&#x2F;002201.html&quot;&gt;WireGuard adds another 40 bytes via its 8-byte UDP header and 32
bytes of protocol-specific data (4-byte type + 4-byte key index +
8-byte nonce + 16-byte authentication
tag)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;m not counting overhead from the outer PPPoE connection and the
TCP&#x2F;IP headers in the user data because these headers are present
regardless.&lt;&#x2F;p&gt;
&lt;p&gt;The performance of putting a tunnel inside another tunnel will
probably not be as good as &lt;em&gt;not&lt;&#x2F;em&gt; putting a tunnel inside another
tunnel. But how bad is it?&lt;&#x2F;p&gt;
&lt;p&gt;John, who did the majority of the implementation, set out to
investigate just how bad this idea actually was.&lt;&#x2F;p&gt;
&lt;p&gt;He initially squeezed a measly 230 Mbps over a connection advertised
as being capable of 940 Mbps, but with some careful tuning of the MTU
and iperf parameters, pushed 680 Mbps of UDP traffic through this
double tunnel setup (see the middle pane in the screenshot below).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;iperf-double-tunnel.jpg&quot; alt=&quot;&quot; &#x2F;&gt; &lt;em&gt;Top pane: pushing the maximum 940 Mbps
of traffic outbound from John&#x27;s home Centurylink GPON service. Middle
Pane: 680 Mbps of UDP traffic received at our router at the SIX!
Bottom pane: Graph of traffic through Bond0.510 --our router&#x27;s
connection with the SIX fabric, and where we peer with HE, indicating
this traffic is going over a peering link rather than a transit link.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Image credit: John Elliott&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;His MikroTik RB5009 sat around 70% CPU during this abuse, indicating
the hardware is sufficient to make line rate (at least for large
packet sizes).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-tunnel-at-all&quot;&gt;Why Tunnel at All?&lt;&#x2F;h2&gt;
&lt;p&gt;Even straightforward VPN tunnels cut into performance. One must wonder
why tunnel at all?&lt;&#x2F;p&gt;
&lt;p&gt;One might use VPN tunnels for financial reasons. Virtual layer 2
circuits, eg. via &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Metro_Ethernet&quot;&gt;metro
ethernet&lt;&#x2F;a&gt; or similar
technologies, are expensive (let&#x27;s not even mention running one&#x27;s own
fiber or fixed wireless). Consumer-grade internet connections are
cheap by comparison.&lt;&#x2F;p&gt;
&lt;p&gt;However, this assumes that one would want to network sites that
already have internet connections together at all. One reason is to
monitor equipment, allow secure remote management, and provide network
services (dns, ntp, etc.) to both equipment and user devices.&lt;&#x2F;p&gt;
&lt;p&gt;I mentioned in the beginning that it could be desirable for traffic
from these sites to exit from a different ASN, opposed to the consumer
ISP connection. Among other things, this allows the ASN owner to
receive and handle DMCA complaints themselves (look for a link here to
our 2021 City of Seattle report that describes the issue). You could
also use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Split_tunneling&quot;&gt;split
tunneling&lt;&#x2F;a&gt; to shed load
from the VPN by routing popular streaming services outside of the
tunnel, for example.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgments&quot;&gt;Acknowledgments&lt;&#x2F;h2&gt;
&lt;p&gt;I owe thanks to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;seattlecommunitynetwork.org&#x2F;&quot;&gt;Seattle Community
Network&lt;&#x2F;a&gt; for providing the
infrastructure necessary to explore this interesting hypothetical.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;johnelliott.org&#x2F;&quot;&gt;John Elliott&lt;&#x2F;a&gt; for doing the
hands-on-keyboard work configuring the network gear, running
performance tests, and providing the traceroutes and screenshots.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;homes.cs.washington.edu&#x2F;~infrared&#x2F;&quot;&gt;Esther Jang&lt;&#x2F;a&gt;
for pre-work in scoping the problem, helping set up the Seattle
Community Network infrastructure on which these experiments were run,
and editing and giving feedback on this article.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;doof.net&#x2F;&quot;&gt;doof.net&lt;&#x2F;a&gt; for providing hosting and
support to Seattle Community Network.&lt;&#x2F;p&gt;
&lt;p&gt;Also thanks to the numerous other volunteers and donors to Seattle
Community Network whose contributions of money, rackspace, bandwidth,
physical space, etc. make the project possible.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;tunnel-downsides&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;One downside I&#x27;ve heard about HE&#x27;s IPv6 tunnel
broker is that some treat it with suspicion. For example, Netflix
blocks it because they can&#x27;t tell which country you&#x27;re connecting
from, and Wikipedia doesn&#x27;t allow edits from these IP blocks.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;bad-performance&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;Namely, the reduced MTU, and the additional
latency caused by the additional processing steps.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;RFC6598&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;Side-note: hop 2, 100.92.123.67, is within the
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc6598&quot;&gt;100.64.0.0&#x2F;10 address space reserved for Carrier-Grade NAT on
provider networks in RFC
6598&lt;&#x2F;a&gt;. I just thought that was
interesting.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;level3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;Centurylink hops through &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Level_3_Communications&quot;&gt;Level3, which became part of
Centurylink,&lt;&#x2F;a&gt;
(which is now Lumen) on its way to HE. Presumably Lumen is not
charging themselves for transit. Comcast connects directly to HE.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
</feed>
