
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Sun, 05 Apr 2026 20:30:41 GMT</lastBuildDate>
        <item>
            <title><![CDATA[How Workers VPC Services connects to your regional private networks from anywhere in the world]]></title>
            <link>https://blog.cloudflare.com/workers-vpc-open-beta/</link>
            <pubDate>Wed, 05 Nov 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Workers VPC Services enter open beta today. We look under the hood to see how Workers VPC connects your globally-deployed Workers to your regional private networks by using Cloudflare's global network, while abstracting cross-cloud networking complexity. ]]></description>
            <content:encoded><![CDATA[ <p>In April, we shared our vision for a <a href="https://blog.cloudflare.com/workers-virtual-private-cloud/"><u>global virtual private cloud on Cloudflare</u></a>, a way to unlock your applications from regionally constrained clouds and on-premise networks, enabling you to build truly cross-cloud applications.</p><p>Today, we’re announcing the first milestone of our Workers VPC initiative: VPC Services. VPC Services allow you to connect to your APIs, containers, virtual machines, serverless functions, databases and other services in regional private networks via <a href="https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/"><u>Cloudflare Tunnels</u></a> from your <a href="https://workers.cloudflare.com/"><u>Workers</u></a> running anywhere in the world. </p><p>Once you set up a Tunnel in your desired network, you can register each service that you want to expose to Workers by configuring its host or IP address. Then, you can access the VPC Service as you would any other <a href="https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/"><u>Workers service binding</u></a> — Cloudflare’s network will automatically route to the VPC Service over Cloudflare’s network, regardless of where your Worker is executing:</p>
            <pre><code>export default {
  async fetch(request, env, ctx) {
    // Perform application logic in Workers here	

    // Call an external API running in a ECS in AWS when needed using the binding
    const response = await env.AWS_VPC_ECS_API.fetch("http://internal-host.com");

    // Additional application logic in Workers
    return new Response();
  },
};</code></pre>
            <p>Workers VPC is now available to everyone using Workers, at no additional cost during the beta, as is Cloudflare Tunnels. <a href="https://dash.cloudflare.com/?to=/:account/workers/vpc/services"><u>Try it out now.</u></a> And read on to learn more about how it works under the hood.</p>
    <div>
      <h2>Connecting the networks you trust, securely</h2>
      <a href="#connecting-the-networks-you-trust-securely">
        
      </a>
    </div>
    <p>Your applications span multiple networks, whether they are on-premise or in external clouds. But it’s been difficult to connect from Workers to your APIs and databases locked behind private networks. </p><p>We have <a href="https://blog.cloudflare.com/workers-virtual-private-cloud/"><u>previously described</u></a> how traditional virtual private clouds and networks entrench you into traditional clouds. While they provide you with workload isolation and security, traditional virtual private clouds make it difficult to build across clouds, access your own applications, and choose the right technology for your stack.</p><p>A significant part of the cloud lock-in is the inherent complexity of building secure, distributed workloads. VPC peering requires you to configure routing tables, security groups and network access-control lists, since it relies on networking across clouds to ensure connectivity. In many organizations, this means weeks of discussions and many teams involved to get approvals. This lock-in is also reflected in the solutions invented to wrangle this complexity: Each cloud provider has their own bespoke version of a “Private Link” to facilitate cross-network connectivity, further restricting you to that cloud and the vendors that have integrated with it.</p><p>With Workers VPC, we’re simplifying that dramatically. You set up your Cloudflare Tunnel once, with the necessary permissions to access your private network. Then, you can configure Workers VPC Services, with the tunnel and hostname (or IP address and port) of the service you want to expose to Workers. Any request made to that VPC Service will use this configuration to route to the given service within the network.</p>
            <pre><code>{
  "type": "http",
  "name": "vpc-service-name",
  "http_port": 80,
  "https_port": 443,
  "host": {
    "hostname": "internally-resolvable-hostname.com",
    "resolver_network": {
      "tunnel_id": "0191dce4-9ab4-7fce-b660-8e5dec5172da"
    }
  }
}</code></pre>
            <p>This ensures that, once represented as a Workers VPC Service, a service in your private network is secured in the same way other Cloudflare bindings are, using the Workers binding model. Let’s take a look at a simple VPC Service binding example:</p>
            <pre><code>{
  "name": "WORKER-NAME",
  "main": "./src/index.js",
  "vpc_services": [
    {
      "binding": "AWS_VPC2_ECS_API",
      "service_id": "5634563546"
    }
  ]
}</code></pre>
            <p>Like other Workers bindings, when you deploy a Worker project that tries to connect to a VPC Service, the access permissions are verified at deploy time to ensure that the Worker has access to the service in question. And once deployed, the Worker can use the VPC Service binding to make requests to that VPC Service — and only that service within the network. </p><p>That’s significant: Instead of exposing the entire network to the Worker, only the specific VPC Service can be accessed by the Worker. This access is verified at deploy time to provide a more explicit and transparent service access control than traditional networks and access-control lists do.</p><p>This is a key factor in the design of Workers bindings: de facto security with simpler management and making Workers immune to Server-Side Request Forgery (SSRF) attacks. <a href="https://blog.cloudflare.com/workers-environment-live-object-bindings/#security"><u>We’ve gone deep on the binding security model in the past</u></a>, and it becomes that much more critical when accessing your private networks. </p><p>Notably, the binding model is also important when considering what Workers are: scripts running on Cloudflare’s global network. They are not, in contrast to traditional clouds, individual machines with IP addresses, and do not exist within networks. Bindings provide secure access to other resources within your Cloudflare account – and the same applies to Workers VPC Services.</p>
    <div>
      <h2>A peek under the hood</h2>
      <a href="#a-peek-under-the-hood">
        
      </a>
    </div>
    <p>So how do VPC Services and their bindings route network requests from Workers anywhere on Cloudflare’s global network to regional networks using tunnels? Let’s look at the lifecycle of a sample HTTP Request made from a VPC Service’s dedicated <b>fetch()</b> request represented here:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4iUTiZjmbm2ujppLugfxJo/4db92fdf8549c239f52d8636e2589baf/image4.png" />
          </figure><p>It all starts in the Worker code, where the <b>.fetch() </b>function of the desired VPC Service is called with a standard JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/API/Request"><u>Request</u></a> (as represented with Step 1). The Workers runtime will use a <a href="https://capnproto.org/"><u>Cap’n Proto</u></a> remote-procedure-call to send the original HTTP request alongside additional context, as it does for many other Workers bindings. </p><p>The Binding Worker of the VPC Service System receives the HTTP request along with the binding context, in this case, the Service ID of the VPC Service being invoked. The Binding Worker will proxy this information to the Iris Service within an HTTP CONNECT connection, a standard pattern across Cloudflare’s bindings to place connection logic to Cloudflare’s edge services within Worker code rather than the Workers runtime itself (Step 2). </p><p>The Iris Service is the main service for Workers VPC. Its responsibility is to accept requests for a VPC Service and route them to the network in which your VPC Service is located. It does this by integrating with <a href="https://blog.cloudflare.com/extending-local-traffic-management-load-balancing-to-layer-4-with-spectrum/#how-we-enabled-spectrum-to-support-private-networks"><u>Apollo</u></a>, an internal service of <a href="https://developers.cloudflare.com/cloudflare-one/?cf_target_id=2026081E85C775AF31266A26CE7F3D4D"><u>Cloudflare One</u></a>. Apollo provides a unified interface that abstracts away the complexity of securely connecting to networks and tunnels, <a href="https://blog.cloudflare.com/from-ip-packets-to-http-the-many-faces-of-our-oxy-framework/"><u>across various layers of networking</u></a>. </p><p>To integrate with Apollo, Iris must complete two tasks. First, Iris will parse the VPC Service ID from the metadata and fetch the information of the tunnel associated with it from our configuration store. This includes the tunnel ID and type from the configuration store (Step 3), which is the information that Iris needs to send the original requests to the right tunnel.</p><p>Second, Iris will create the UDP datagrams containing DNS questions for the A and AAAA records of the VPC Service’s hostname. These datagrams will be sent first, via Apollo. Once DNS resolution is completed, the original request is sent along, with the resolved IP address and port (Step 4). That means that steps 4 through 7 happen in sequence twice for the first request: once for DNS resolution and a second time for the original HTTP Request. Subsequent requests benefit from Iris’ caching of DNS resolution information, minimizing request latency.</p><p>In Step 5, Apollo receives the metadata of the Cloudflare Tunnel that needs to be accessed, along with the DNS resolution UDP datagrams or the HTTP Request TCP packets. Using the tunnel ID, it determines which datacenter is connected to the Cloudflare Tunnel. This datacenter is in a region close to the Cloudflare Tunnel, and as such, Apollo will route the DNS resolution messages and the Original Request to the Tunnel Connector Service running in that datacenter (Step 5).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6eXnv33qvTvGRRNGqS9ywj/99e57beeaa32de0724c6c9f396ab3b17/image3.png" />
          </figure><p>The Tunnel Connector Service is responsible for providing access to the Cloudflare Tunnel to the rest of Cloudflare’s network. It will relay the DNS resolution questions, and subsequently the original request to the tunnel over the QUIC protocol (Step 6).</p><p>Finally, the Cloudflare Tunnel will send the DNS resolution questions to the DNS resolver of the network it belongs to. It will then send the original HTTP Request from its own IP address to the destination IP and port (Step 7). The results of the request are then relayed all the way back to the original Worker, from the datacenter closest to the tunnel all the way to the original Cloudflare datacenter executing the Worker request.</p>
    <div>
      <h2>What VPC Service allows you to build</h2>
      <a href="#what-vpc-service-allows-you-to-build">
        
      </a>
    </div>
    <p>This unlocks a whole new tranche of applications you can build on Cloudflare. For years, Workers have excelled at the edge, but they've largely been kept "outside" your core infrastructure. They could only call public endpoints, limiting their ability to interact with the most critical parts of your stack—like a private accounts API or an internal inventory database. Now, with VPC Services, Workers can securely access those private APIs, databases, and services, fundamentally changing what's possible.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/DDDzgVtHtK92DZ4LwKhLI/904fc30fcab4797fd6ee263f09b85ab1/image2.png" />
          </figure><p>This immediately enables true cross-cloud applications that span Cloudflare Workers and any other cloud like AWS, GCP or Azure. We’ve seen many customers adopt this pattern over the course of our private beta, establishing private connectivity between their external clouds and Cloudflare Workers. We’ve even done so ourselves, connecting our Workers to Kubernetes services in our core datacenters to power the control plane APIs for many of our services. Now, you can build the same powerful, distributed architectures, using Workers for global scale while keeping stateful backends in the network you already trust.</p><p>It also means you can connect to your on-premise networks from Workers, allowing you to modernize legacy applications with the performance and infinite scale of Workers. More interesting still are some emerging use cases for developer workflows. We’ve seen developers run <a href="https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/"><code><u>cloudflared</u></code></a> on their laptops to connect a deployed Worker back to their local machine for real-time debugging. The full flexibility of Cloudflare Tunnels is now a programmable primitive accessible directly from your Worker, opening up a world of possibilities.</p>
    <div>
      <h2>The path ahead of us</h2>
      <a href="#the-path-ahead-of-us">
        
      </a>
    </div>
    <p>VPC Services is the first milestone within the larger Workers VPC initiative, but we’re just getting started. Our goal is to make connecting to any service and any network, anywhere in the world, a seamless part of the Workers experience. Here’s what we’re working on next:</p><p><b>Deeper network integration</b>. Starting with Cloudflare Tunnels was a deliberate choice. It's a highly available, flexible, and familiar solution, making it the perfect foundation to build upon. To provide more options for enterprise networking, we're going to be adding support for standard IPsec tunnels, Cloudflare Network Interconnect (CNI), and AWS Transit Gateway, giving you and your teams more choices and potential optimizations. Crucially, these connections will also become truly bidirectional, allowing your private services to initiate connections back to Cloudflare resources such as pushing events to Queues or fetching from R2.</p><p><b>Expanded protocol and service support. </b>The next step beyond HTTP is enabling access to TCP services. This will first be achieved by integrating with Hyperdrive. We're evolving the previous Hyperdrive support for private databases to be simplified with VPC Services configuration, avoiding the need to add Cloudflare Access and manage security tokens. This creates a more native experience, complete with Hyperdrive's powerful connection pooling. Following this, we will add broader support for raw TCP connections, unlocking direct connectivity to services like Redis caches and message queues from <a href="https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/"><code><u>Workers ‘connect()’</u></code></a>.</p><p><b>Ecosystem compatibility. </b>We want to make connecting to a private service feel as natural as connecting to a public one. To do so, we will be providing a unique autogenerated hostname for each Workers VPC Service, similar to <a href="https://developers.cloudflare.com/hyperdrive/get-started/#write-a-worker"><u>Hyperdrive’s connection strings</u></a>. This will make it easier to use Workers VPC with existing libraries and object–relational mapping libraries that may require a hostname (e.g., in a global ‘<code>fetch()</code>’ call or a MongoDB connection string). Workers VPC Service hostname will automatically resolve and route to the correct VPC Service, just as the ‘<code>fetch()</code>’ command does.</p>
    <div>
      <h2>Get started with Workers VPC</h2>
      <a href="#get-started-with-workers-vpc">
        
      </a>
    </div>
    <p>We’re excited to release Workers VPC Services into open beta today. We’ve spent months building out and testing our first milestone for Workers to private network access. And we’ve refined it further based on feedback from both internal teams and customers during the closed beta. </p><p><b>Now, we’re looking forward to enabling everyone to build cross-cloud apps on Workers with Workers VPC, available for free during the open beta.</b> With Workers VPC, you can bring your apps on private networks to region Earth, closer to your users and available to Workers across the globe.</p><p><a href="https://dash.cloudflare.com/?to=/:account/workers/vpc/services"><b><u>Get started with Workers VPC Services for free now.</u></b></a></p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Workers VPC]]></category>
            <category><![CDATA[Cloudflare Tunnel]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Hybrid Cloud]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[VPC]]></category>
            <category><![CDATA[Private Network]]></category>
            <guid isPermaLink="false">3nRyPdIVogbDGSeUZgRY41</guid>
            <dc:creator>Thomas Gauvin</dc:creator>
            <dc:creator>Matt Alonso</dc:creator>
            <dc:creator>Eric Falcão</dc:creator>
        </item>
        <item>
            <title><![CDATA[BGP zombies and excessive path hunting]]></title>
            <link>https://blog.cloudflare.com/going-bgp-zombie-hunting/</link>
            <pubDate>Fri, 31 Oct 2025 15:30:00 GMT</pubDate>
            <description><![CDATA[ A BGP “zombie” is essentially a route that has become stuck in the Default-Free Zone (DFZ) of the Internet, potentially due to a missed or lost prefix withdrawal. We’ll walk through some situations where BGP zombies are more likely to rise from the dead and wreak havoc.
 ]]></description>
            <content:encoded><![CDATA[ <p>Here at Cloudflare, we’ve been celebrating Halloween with some zombie hunting of our own. The zombies we’d like to remove are those that disrupt the core framework responsible for how the Internet routes traffic: <a href="http://cloudflare.com/learning/security/glossary/what-is-bgp/"><u>BGP (Border Gateway Protocol)</u></a>.</p><p>A <a href="https://dl.acm.org/doi/10.1145/3472305.3472315"><u>BGP zombie</u></a> is a silly name for a route that has become stuck in the Internet’s <a href="https://en.wikipedia.org/wiki/Default-free_zone"><u>Default-Free Zone</u></a>, aka the DFZ: the collection of all internet routers that do not require a default route, potentially due to a missed or lost prefix withdrawal.</p><p>The underlying root cause of a zombie could be multiple things, spanning from buggy software in routers or just general route processing slowness. It’s when a BGP prefix is meant to be gone from the Internet, but for one reason or another it becomes a member of the undead and hangs around for some period of time.</p><p>The longer these zombies linger, the more they create operational impact and become a real headache for network operators. Zombies can lead packets astray, either by trapping them inside of route loops or by causing them to take an excessively scenic route. Today, we’d like to celebrate Halloween by covering how BGP zombies form and how we can lessen the likelihood that they wreak havoc on Internet traffic.</p>
    <div>
      <h2>Path hunting</h2>
      <a href="#path-hunting">
        
      </a>
    </div>
    <p>To understand the slowness that can often lead to BGP zombies, we need to talk about path hunting. <a href="https://www.noction.com/blog/bgp-path-hunting"><u>Path hunting</u></a> occurs when routers running BGP exhaustively search for the best path to a prefix as determined by <a href="https://en.wikipedia.org/wiki/Longest_prefix_match"><u>Longest Prefix Matching</u></a> (LPM) and BGP routing attributes like path length and local preference. This becomes relevant in our observations of exactly how routes become stuck, for how long they become stuck, and how visible they are on the Internet.</p><p>For example, path hunting happens when a more-specific BGP prefix is withdrawn from the global routing table, and networks need to fallback to a less-specific BGP advertisement. In this example, we use 2001:db8::/48 for the more-specific BGP announcement and 2001:db8::/32 for the less-specific prefix. When the /48 is withdrawn by the originating <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>Autonomous System</u></a> (AS), BGP routers have to recognize that route as missing and begin routing traffic to IPs such as 2001:db8::1 via the 2001:db8::/32 route, which still remains while the prefix 2001:db8::/48 is gone. </p><p>Let’s see what this could look like in action with a few diagrams. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7xRNAHChJUyiMbtBZyLOlF/973d10be053b7b7f088721389c34c10e/BLOG-3059_2.png" />
          </figure><p><sub><i>Diagram 1: Active 2001:db8::/48 route</i></sub></p><p>In this initial state, 2001:db8::/48 is used actively for traffic forwarding, which all flows through AS13335 on the way to AS64511. In this case, AS64511 would be a BYOIP customer of Cloudflare. AS64511 also announces a <i>backup</i> route to another Internet Service Provider (ISP), AS64510, but this route is not active even in AS64510’s routing table for forwarding to 2001:db8::1 because 2001:db8::/48 is a longer prefix match when compared to 2001:db8::/32.</p><p>Things get more interesting when AS64510 signals for 2001:db8::/48 to be withdrawn by Cloudflare (AS13335), perhaps because a DDoS attack is over and the customer opts to use Cloudflare only when they are actively under attack.</p><p>When the customer signals to Cloudflare (via BGP Control or API call) to withdraw the 2001:db8::/48 announcement, all BGP routers have to <a href="https://en.wikipedia.org/wiki/Convergence_(routing)"><u>converge</u></a> upon this update, which involves path hunting. AS13335 sends a BGP withdrawal message for 2001:db8::/48 to its directly-connected BGP neighbors. While the news of withdrawal may travel quickly from AS13335 to the other networks, news may travel more quickly to some of the neighbors than others. This means that until everyone has received and processed the withdrawal, networks may try routing through one another to reach the 2001:db8::/48 prefix – even after AS13335 has withdrawn it. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7h3Vba4T7tm6XPB2pIyQex/f5f7c27148bed4dd72959b3820d045ac/BLOG-3059_3.png" />
          </figure><p><sub><i>Diagram 2: 2001:db8::/48 route withdrawn via AS13335</i></sub></p><p>Imagine AS64501 is a little slower than the rest – perhaps due to using older hardware, hardware being overloaded, a software bug, specific configuration settings, poor luck, or some other factor – and still has not processed the withdrawal of the /48. This in itself could be a BGP zombie, since the route is stuck for a small period. Our pings toward 2001:db8::1 are never able to actually reach AS64511, because AS13335 knows the /48 is meant to be withdrawn, but some routers carrying a full table have not yet converged upon that result.</p><p>The length of time spent path hunting is amplified by something called the Minimum Route Advertisement Interval (MRAI). The MRAI specifies the minimum amount of time between BGP advertisement messages from a BGP router, meaning it introduces a purposeful number of seconds of delay between each BGP advertisement update. <a href="https://datatracker.ietf.org/doc/html/rfc4271"><u>RFC4271</u></a> recommends an MRAI value of 30-seconds for eBGP updates, and while this can cut down on the chattiness of BGP, or even potential oscillation of updates, it also makes path hunting take longer. </p><p>At the next cycle of path hunting, even AS64501, which was previously still pointing toward a nonexistent /48 route from AS13335, should find the /32 advertisement is all that is left toward 2001:db8::1. Once it has done so, the traffic flow will become the following: </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5sCGMS95R8y32WTjnUigfN/1e5c9a7551c572a08596985edac5c17b/BLOG-3059_4.png" />
          </figure><p><sub><i>Diagram 3: Routing fallback to 2001:db8::/32 and 2001:db8::/48 is gone from DFZ</i></sub></p><p>This would mean BGP path hunting is over, and the Internet has realized that the 2001:db8::/32 is the best route available toward 2001:db8::1, and that 2001:db8::/48 is really gone. While in this example we’ve purposely made path hunting only last two cycles, in reality it can be far more, especially with how highly connected AS13335 is to thousands of peer networks and <a href="https://en.wikipedia.org/wiki/Tier_1_network"><u>Tier-1</u></a>’s globally. </p><p>Now that we’ve discussed BGP path hunting and how it works, you can probably already see how a BGP zombie outbreak can begin and how routing tables can become stuck for a lengthy period of time. Excessive BGP path hunting for a previously-known more-specific prefix can be an early indicator that a zombie could follow.</p>
    <div>
      <h2>Spawning a zombie</h2>
      <a href="#spawning-a-zombie">
        
      </a>
    </div>
    <p>Zombies have captured our attention more recently as they were noticed by some of our customers leveraging <a href="https://developers.cloudflare.com/byoip/"><u>Bring-Your-Own-IP (BYOIP)</u></a> on-demand advertisement for <a href="https://www.cloudflare.com/en-gb/network-services/products/magic-transit/"><u>Magic Transit</u></a>. BYOIP may be configured in two modes: "always-on", in which a prefix is continuously announced, or "on-demand", where a prefix is announced only when a customer chooses to. For some on-demand customers, announcement and withdrawal cycles <i>may</i> be a more frequent occurrence, which can lead to an increase in BGP zombies.</p><p>With that in mind and also knowing how path hunting works, let’s spawn our own zombie onto the Internet. To do so, we’ll take a spare block of IPv4 and IPv6 and announce them like so:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/20shWBMhqLR3tBMh50v7Uy/bf40e90c2f6a506a5bcfc9bafd1e31d2/BLOG-3059_5.png" />
          </figure><p>Once the routes are announced and stable, we’ll then proceed to withdraw the more specific routes advertised via Cloudflare globally. With a few quick clicks, we’ve successfully re-animated the dead.</p><p><i>Variant A: Ghoulish Gateways</i></p><p>One place zombies commonly occur is between upstream ISPs. When one router in a given ISP’s network is a little slower to update, routes can become stuck. </p><p>Take, for example, the following loop we observed between two of our upstream partners:</p>
            <pre><code>7. be2431.ccr31.sjc04.atlas.cogentco.com
8. tisparkle.sjc04.atlas.cogentco.com
9. 213.144.177.184
10. 213.144.177.184
11. 89.221.32.227
12. (waiting for reply)
13. be2749.rcr71.goa01.atlas.cogentco.com
14. be3219.ccr31.mrs02.atlas.cogentco.com
15. be2066.agr21.mrs02.atlas.cogentco.com
16. telecomitalia.mrs02.atlas.cogentco.com
17. 213.144.177.186
18. 89.221.32.227</code></pre>
            <p></p><p>Or this loop - observed on the same withdrawal test - between two different providers:  </p>
            <pre><code>15. if-bundle-12-2.qcore2.pvu-paris.as6453.net
16. if-bundle-56-2.qcore1.fr0-frankfurt.as6453.net
17. if-bundle-15-2.qhar1.fr0-frankfurt.as6453.net
18. 195.219.223.11
19. 213.144.177.186
20. 195.22.196.137
21. 213.144.177.186
22. 195.22.196.137</code></pre>
            <p><i></i></p><p><i>Variant B: Undead LAN (Local Area Network)</i></p><p>Simultaneously, zombies can occur entirely within a given network. When a route is withdrawn from Cloudflare’s network, each device in our network must individually begin the process of withdrawing the route. While this is generally a smooth process, things can still become stuck.</p><p>Take, for instance, a situation where one router inside of our network has not yet fully processed the withdrawal. Connectivity partners will continue routing traffic towards that router (as they have not yet received the withdrawal) while no host remains behind the router which is capable of actually processing the traffic. The result is an internal-only looping path:</p>
            <pre><code>10. 192.0.2.112
11. 192.0.2.113
12. 192.0.2.112
13. 192.0.2.113
14. 192.0.2.112
15. 192.0.2.113
16. 192.0.2.112
17. 192.0.2.113
18. 192.0.2.112
19. 192.0.2.113
</code></pre>
            <p></p><p>Unlike most fictionally-depicted hoards of the walking dead, our highly-visible zombie has a limited lifetime in most major networks – in this instance, only around around 6 minutes, after which most had re-converged around the less-specific as the best path. Sadly, this is on the shorter side – in some cases, we have seen long-lived zombies cause reachability issues for more than 10 minutes. It’s safe to say this is longer than most network operators would expect BGP convergence to take in a normal situation. </p><p>But, you may ask – is this the excessive path hunting we talked about earlier, or a BGP zombie? Really, it depends on the expectation and tolerance around <a href="https://dl.acm.org/doi/10.1145/3472305.3472315"><u>how long BGP convergence</u></a> should take to process the prefix withdrawal. In any case, even over 30 minutes after our withdrawal of our more-specific prefix, we are able to see zombie routes in the route-views public collectors easily:</p>
            <pre><code>~ % monocle search --start-ts 2025-10-28T12:40:13Z --end-ts 2025-10-28T13:00:13Z --prefix 198.18.0.0/24
A|1761656125.550447|206.82.105.116|54309|198.18.0.0/24|54309 13335 395747|IGP|206.82.104.31|0|0|54309:111|false|||route-views.ny

</code></pre>
            <p></p><p>You might argue that six to eleven minutes (or more) is a reasonable time for worst-case BGP convergence in the Tier-1 network layer, though that itself seems like a stretch. Even setting that aside, our data shows that very real BGP zombies exist in the global routing table, and they will negatively impact traffic. Curiously, we observed the path hunting delay is worse on IPv4, with the longest observed IPv6 impact in major (Tier-1) networks being just over 4 minutes. One could speculate this is in part due to the <a href="https://bgp.potaroo.net/index-bgp.html"><u>much higher number</u></a> of IPv4 prefixes in the Internet global routing table than the IPv6 global table, and how BGP speakers handle them separately.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4WOQBZb7MV2a5PA84xm6Be/28e252e5212781ae2d477150692605db/25x_10fps_a.gif" />
          </figure><p><sub><i>Source: RIPEstat’s BGPlay</i></sub></p><p>Part of the delay appears to originate from how interconnected AS13335 is; being heavily peered with a large portion of the Internet increases the likelihood of a route becoming stuck in a given location. Given that, perhaps a zombie would be shorter-lived if we operated in the opposite direction: announcing a less-specific persistently to 13335 and announcing more specifics via our local ISP during normal operation. Since the withdrawal will come from what is likely a less well-peered network, the time-to-convergence may be shorter:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4O7r3Nffpbus6ht3Eo6eiF/a7d577042e43c9b4da988cf9bd29f6fe/BLOG-3059_7.png" />
          </figure><p>Indeed, as predicted, we still get a stuck route, and it only lives for around 20 seconds in the Tier-1 network layer:</p>
            <pre><code>19. be12488.ccr42.ams03.atlas.cogentco.com
20. 38.88.214.142
21. be2020.ccr41.ams03.atlas.cogentco.com
22. 38.88.214.142
23. (waiting for reply)
24. 38.88.214.142
25. (waiting for reply)
26. 38.88.214.142
</code></pre>
            <p></p><p>Unfortunately, that 20 seconds is still an impactful 20 seconds - while better, it’s not where we want to be. The exact length of time will depend on the native ISP networks one is connected with, and it could certainly ease into the minutes worth of stuck routing. </p><p>In both cases, the initial time-to-announce yielded no loss, nor was a zombie created, as both paths remained valid for the entirety of their initial lifetime. Zombies were only created when a more specific prefix was fully withdrawn. A newly-announced route is not subject to path hunting in the same way a withdrawn more-specific route is. As they say, good (new) news travels fast.</p>
    <div>
      <h2>Lessening the zombie outbreak</h2>
      <a href="#lessening-the-zombie-outbreak">
        
      </a>
    </div>
    <p>Our findings lead us to believe that the withdrawal of a more-specific prefix may lead to zombies running rampant for longer periods of time. Because of this, we are exploring some improvements that make the consequences of BGP zombie routing less impactful for our customers relying on our on-demand BGP functionality.</p><p>For the traffic that <b>does</b> reach Cloudflare with stuck routes, we will introduce some BGP traffic forwarding improvements internally that allow for a more graceful withdrawal of traffic, even if routes are erroneously pointing toward us. In many ways, this will closely resemble the BGP <a href="https://www.rfc-editor.org/rfc/rfc1997.html"><u>well-known no-export</u></a> community’s functionality from our servers running BGP. This means even if we receive traffic from external parties due to stuck routing, we will still have the opportunity to deliver traffic to our far-end customers over a tunneled connection or via a <a href="https://www.cloudflare.com/network-services/products/network-interconnect/"><u>Cloudflare Network Interconnect</u></a> (CNI). We look forward to reporting back the positive impact after making this improvement for a more graceful draining of traffic by default. </p><p>For the traffic that <b>does not</b> reach Cloudflare’s edge, and instead loops between network providers, we need to use a different approach. Since we know more-specific to less-specific prefix routing fallback is more prone to BGP zombie outbreak, we are encouraging customers to instead use a multi-step draining process when they want traffic drained from the Cloudflare edge for an on-demand prefix without introducing route loops or blackhole events. The draining process when removing traffic for a BYOIP prefix from Cloudflare should look like this: </p><ol><li><p>The customer is already announcing an example prefix from Cloudflare, ex. 198.18.0.0/24</p></li><li><p>The customer begins <i>natively </i>announcing the prefix 198.18.0.0/24 (i.e. the same-length as the prefix they are advertising via Cloudflare) from their network to the Internet Service Providers that they wish to fail over traffic to.</p></li><li><p>After a few minutes, the customer signals BGP withdrawal from Cloudflare for the 198.18.0.0/24 prefix.</p></li></ol><p>The result is a clean cut over: impactful zombies are avoided because the same-length prefix (198.18.0.0/24) remains in the global routing table. Excessive path hunting is avoided because instead of routers needing to aggressively seek out a missing more-specific prefix match, they can fallback to the same-length announcement that persists in the routing table from the natively-originated path to the customer’s network.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/KmRvPsGUOp5PsNXcKCE1F/78f2c29c8c278d158972114df875ad0c/25x_10fps_b.gif" />
          </figure><p><sub><i>Source: RIPEstat’s BGPlay</i></sub></p>
    <div>
      <h2>What next?</h2>
      <a href="#what-next">
        
      </a>
    </div>
    <p>We are going to continue to refine our methods of measuring BGP zombies, so you can look forward to more insights in the future. There is also <a href="https://www.thousandeyes.com/bgp-stuck-route-observatory/"><u>work from others</u></a> in the <a href="https://blog.benjojo.co.uk/post/bgp-stuck-routes-tcp-zero-window"><u>community</u></a> around zombie measurement that is interesting and producing useful data. In terms of combatting the software bugs around BGP zombie creation, routing vendors should implement <a href="https://datatracker.ietf.org/doc/html/rfc9687"><u>RFC9687</u></a>, the BGP SendHoldTimer. The general idea is that a local router can detect via the SendHoldTimer if the far-end router stops processing BGP messages unexpectedly, which lowers the possibility of zombies becoming stuck for long periods of time. </p><p>In addition, it’s worth keeping in mind our observations made in this post about more-specific prefix announcements and excessive path hunting. If as a network operator you rely on more-specific BGP prefix announcements for failover, or for traffic engineering, you need to be aware that routes could become stuck for a longer period of time before full BGP convergence occurs.</p><p>If you’re interested in problems like BGP zombies, consider <a href="https://www.cloudflare.com/en-gb/careers/jobs/?location=default"><u>coming to work</u></a> at Cloudflare or applying for an <a href="https://www.cloudflare.com/en-gb/careers/early-talent/"><u>internship</u></a>. Together we can help build a better Internet!  </p> ]]></content:encoded>
            <category><![CDATA[BGP]]></category>
            <category><![CDATA[Routing]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[BYOIP]]></category>
            <guid isPermaLink="false">6Qk6krBb9GkFrf67N6NhyW</guid>
            <dc:creator>Bryton Herdes</dc:creator>
            <dc:creator>June Slater</dc:creator>
            <dc:creator>Mingwei Zhang</dc:creator>
        </item>
        <item>
            <title><![CDATA[Network performance update: Developer Week 2025]]></title>
            <link>https://blog.cloudflare.com/network-performance-update-developer-week-2025/</link>
            <pubDate>Wed, 09 Apr 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare has been tracking and comparing our speed with other top networks since 2021. Let’s take a look at how things have changed since our last update. ]]></description>
            <content:encoded><![CDATA[ <p>As the Internet has become enmeshed in our everyday lives, so has our need for speed. No one wants to wait when adding shoes to our shopping carts, or accessing corporate assets from across the globe. And as the Internet supports more and more of our critical infrastructure, speed becomes more than just a measure of how quickly we can place a takeout order. It becomes the connective tissue between the systems that keep us safe, healthy, and organized. Governments, financial institutions, healthcare ecosystems, transit — they increasingly rely on the Internet. This is why at Cloudflare, building the fastest network is our north star. </p><p>We’re happy to announce that we are the fastest network in 48% of the top 1000 networks by 95th percentile TCP connection time between November 2024, and March 2025, up from 44% in September 2024.</p><p>In this post, we’re going to share with you how our network performance has changed since our <a href="https://blog.cloudflare.com/network-performance-update-birthday-week-2024/"><u>last post in September 2024</u></a>, and talk about what makes us faster than other networks.  But first, let’s talk a little bit about how we get this data.</p>
    <div>
      <h2>How does Cloudflare get this data?</h2>
      <a href="#how-does-cloudflare-get-this-data">
        
      </a>
    </div>
    <p>It’s happened to all of us — you casually click on a site, and suddenly you’ve reached a Cloudflare-branded error page. While you are shaking your fist at the sky, something interesting is happening on the back end. Cloudflare is using <a href="https://www.w3.org/TR/user-timing/"><u>Real User Monitoring (RUM)</u></a> to collect the data used to compare our performance against other networks. The monitoring we do is slightly different than the <a href="https://www.cloudflare.com/application-services/solutions/app-performance-monitoring/"><u>RUM Cloudflare offers</u></a> to customers. When the error page loads, a 100 KB file is fetched and loaded. This file is hosted on networks like Cloudflare, Akamai, Amazon CloudFront, Fastly, and Google Cloud CDN. Your browser processes the performance data, and sends it to Cloudflare, where we use it to get a clear view of how these different networks stack up in terms of speed. </p><p>We’ve been collecting and refining this data since June 2021.  You can read more about how we collect that data <a href="https://blog.cloudflare.com/benchmarking-edge-network-performance/"><u>here</u></a>, and we regularly <a href="https://blog.cloudflare.com/tag/network-performance-update/"><u>track our performance</u></a> during Innovation Weeks to hold ourselves accountable to you that we are always in pursuit of being the fastest network in the world.</p>
    <div>
      <h2>How are we doing?</h2>
      <a href="#how-are-we-doing">
        
      </a>
    </div>
    <p>In order to evaluate Cloudflare’s speed relative to others, we measure performance across the top 1000 “eyeball” networks using the list provided by the <a href="https://stats.labs.apnic.net/cgi-bin/aspop?c=IN"><u>Asia Pacific Network Information Centre (APNIC)</u></a>. So-called “eyeball” networks are those with a large concentration of subscribers/end users.  This information is important, because it gives us signals for where we can expand our presence or peering, or optimize our traffic engineering. When benchmarking, we assess the 95th percentile TCP connection time. This is the time it takes a user to establish a TCP connection to the server they are trying to reach. This metric helps us illustrate how Cloudflare’s network makes your traffic faster by serving your customers as locally as possible. </p><p>When we look at Cloudflare’s performance across the top 1000 networks, we can see that we’re fastest in 487, or over 48%, of these networks, between November 2024 and March 2025:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2vkfABpKwZtd7FJf5BU4lz/c2a778435be9b2c47656753cdb39e8f0/1.png" />
          </figure><p>In <a href="https://blog.cloudflare.com/network-performance-update-birthday-week-2024/"><u>September 2024</u></a>, we ranked #1 in 44% of these networks:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/105vHx9riLNO4Fgm5XvxnL/4b7d106b84d90bcc674c3fb54043593c/2.png" />
          </figure><p>So why did we jump?  To get a better understanding of why, let’s take a look at the countries where we improved, which will give us a better sense of where to dive in.  This is what our network map looked like in <a href="https://blog.cloudflare.com/network-performance-update-birthday-week-2024/"><u>September 2024</u></a> (grey countries mean we do not have enough data or users to derive insights):</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5IfSvKcdYDsTE2Rl2WPLpE/1814ef571b8622c83ff6817b41102cf5/3.png" />
          </figure><p>(September 2024)</p><p>Today, using those same 95th percentile TCP connect times, we rank #1 in 48% of networks and the network map looks like this:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/xYWPvT0dQH7eCxbqNSrqv/e758b2961faad0cd5e1d1d6a72351131/4.png" />
          </figure><p>(March 2025)</p><p>We made most of our gains in Africa, where countries that previously didn’t have enough samples saw an increase in samples, and Cloudflare pulled ahead. This could mean that there was either an increase in Cloudflare users, or an increase in error pages shown. These countries got faster almost exclusively due to the presence of our <a href="https://blog.cloudflare.com/how-cloudflare-helps-next-generation-markets/"><u>Edge Partner deployments</u></a>, which are Cloudflare locations embedded in last mile networks.  In next-generation markets like many African countries, these locations are crucial towards being faster as connectivity to end users tends to fall back to places like South Africa or London if in-country peering does not exist.</p><p>But let’s take a look at a couple of other places and see why we got faster.</p><p>In Canada, we were not the fastest in September 2024, but we are the fastest today. Today, we are the fastest in 40% of networks, which is the most out of all of our competitors:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6bWdN0wG9g1LhujV4lY5Ne/5cdaa76a27cacc487622c45ab0ea38cd/5.png" />
          </figure><p>But when you look at the overall country numbers, we see that the race for the fastest network is quite close:</p><div>
    <figure>
        <table>
            <colgroup>
                <col></col>
                <col></col>
                <col></col>
                <col></col>
            </colgroup>
            <tbody>
                <tr>
                    <td>
                        <p><span><span><strong>Canada 95th Percentile TCP Connect Time by Provider</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span><strong>Rank</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Entity</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Connect Time (P95)</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>#1 Diff</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>1</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Cloudflare</span></span></p>
                    </td>
                    <td>
                        <p><span><span>179 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>-</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>2</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Fastly</span></span></p>
                    </td>
                    <td>
                        <p><span><span>180 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+0.48% (+0.87 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>3</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Google</span></span></p>
                    </td>
                    <td>
                        <p><span><span>180 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+0.74% (+1.32 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>4</span></span></p>
                    </td>
                    <td>
                        <p><span><span>CloudFront</span></span></p>
                    </td>
                    <td>
                        <p><span><span>182 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+1.74% (+3.11 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>5</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Akamai</span></span></p>
                    </td>
                    <td>
                        <p><span><span>215 ms </span></span></p>
                    </td>
                    <td>
                        <p><span><span>+20% (+36 ms)</span></span></p>
                    </td>
                </tr>
            </tbody>
        </table>
    </figure>
</div><p>The difference between Cloudflare and the third-fastest network is a little over a millisecond!  As we’ve <a href="https://blog.cloudflare.com/network-performance-update-birthday-week-2024/"><u>pointed out previously</u></a>, such fluctuations are quite common, especially at higher percentiles.  But there is still a significant difference between us and the slowest network; we’re around 20% faster.</p><p>However, looking at a place like Japan where were not the fastest in September 2024 but are now the fastest, there is a significant difference between Cloudflare and the number two network:</p><div>
    <figure>
        <table>
            <colgroup>
                <col></col>
                <col></col>
                <col></col>
                <col></col>
            </colgroup>
            <tbody>
                <tr>
                    <td>
                        <p><span><span><strong>Japan 95th Percentile TCP Connect Time by Provider</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span><strong>Rank</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Entity</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>Connect Time (P95)</strong></span></span></p>
                    </td>
                    <td>
                        <p><span><span><strong>#1 Diff</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>1</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Cloudflare</span></span></p>
                    </td>
                    <td>
                        <p><span><span>116 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>-</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>2</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Fastly</span></span></p>
                    </td>
                    <td>
                        <p><span><span>122 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+5.23% (+6.08 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>3</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Google</span></span></p>
                    </td>
                    <td>
                        <p><span><span>124 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+6.21% (+7.22 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>4</span></span></p>
                    </td>
                    <td>
                        <p><span><span>CloudFront</span></span></p>
                    </td>
                    <td>
                        <p><span><span>127 ms</span></span></p>
                    </td>
                    <td>
                        <p><span><span>+8.91% (+10 ms)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>5</span></span></p>
                    </td>
                    <td>
                        <p><span><span>Akamai</span></span></p>
                    </td>
                    <td>
                        <p><span><span>153 ms </span></span></p>
                    </td>
                    <td>
                        <p><span><span>+32% (+37 ms)</span></span></p>
                    </td>
                </tr>
            </tbody>
        </table>
    </figure>
</div><p>Why is this? We are in more locations in Japan than our competitors and added more Edge Partner deployments in these locations, bringing us even closer to end-users. Edge Partner deployments are collaborations with ISPs, where we take space in their data centers, and peer with them directly. </p>
    <div>
      <h2>Why?</h2>
      <a href="#why">
        
      </a>
    </div>
    <p>Why do we track our network performance like this? The answer is simple: to improve user experience. This data allows us to track a key performance metric for Cloudflare and the other networks. When we see that we’re lagging in a region, it serves as a signal to dig deeper into our network. </p><p>This data is a gold mine for the teams tasked with improving Cloudflare’s network. When there are countries where Cloudflare is behind, it gives us signals for where we should expand or investigate. If we’re slow, we may need to invest in additional peering. If a region we have invested in heavily is slower, we may need to investigate our hardware.  The example from Japan shows exactly how this can benefit: we took a location where we were previously on par with our competitors, added peering in new locations, and we pulled ahead. </p><p>On top of this map, we have <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>autonomous system (ASN)</u></a> level granularity on how we are performing on each one of the top 1000 eyeball networks, and we continuously optimize our traffic flow with each of them.  This allows us to track individual networks that may lag and improve the customer experience in those networks through turning up peering, or even adding new deployments in those regions. </p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We’re sharing our updates on our journey to become #1 everywhere so that you can see what goes into running the fastest network in the world. From here, our plan is the same as always: identify where we’re slower, fix it, and then tell you how we’ve gotten faster.</p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Network Performance Update]]></category>
            <guid isPermaLink="false">2O9xvScPSeNZVBqldw8qgs</guid>
            <dc:creator>Emily Music</dc:creator>
            <dc:creator>Onur Karaagaoglu</dc:creator>
        </item>
        <item>
            <title><![CDATA[QUIC action: patching a broadcast address amplification vulnerability]]></title>
            <link>https://blog.cloudflare.com/mitigating-broadcast-address-attack/</link>
            <pubDate>Mon, 10 Feb 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare was recently contacted by researchers who discovered a broadcast amplification vulnerability through their QUIC Internet measurement research. We've implemented a mitigation. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare was recently contacted by a group of anonymous security researchers who discovered a broadcast amplification vulnerability through their <a href="https://blog.cloudflare.com/tag/quic"><u>QUIC</u></a> Internet measurement research. Our team collaborated with these researchers through our Public Bug Bounty program, and worked to fully patch a dangerous vulnerability that affected our infrastructure.</p><p>Since being notified about the vulnerability, we've implemented a mitigation to help secure our infrastructure. According to our analysis, we have fully patched this vulnerability and the amplification vector no longer exists. </p>
    <div>
      <h3>Summary of the amplification attack</h3>
      <a href="#summary-of-the-amplification-attack">
        
      </a>
    </div>
    <p>QUIC is an Internet transport protocol that is encrypted by default. It offers equivalent features to <a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/"><u>TCP</u></a> (Transmission Control Protocol) and <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> (Transport Layer Security), while using a shorter handshake sequence that helps reduce connection establishment times. QUIC runs over <a href="https://www.cloudflare.com/en-gb/learning/ddos/glossary/user-datagram-protocol-udp/"><u>UDP</u></a> (User Datagram Protocol).</p><p>The researchers found that a single client QUIC <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-17.2.2"><u>Initial packet</u></a> targeting a broadcast IP destination address could trigger a large response of initial packets. This manifested as both a server CPU amplification attack and a reflection amplification attack.</p>
    <div>
      <h3>Transport and security handshakes</h3>
      <a href="#transport-and-security-handshakes">
        
      </a>
    </div>
    <p>When using TCP and TLS there are two handshake interactions. First, is the TCP 3-way transport handshake. A client sends a SYN packet to a server, it responds with a SYN-ACK to the client, and the client responds with an ACK. This process validates the client IP address. Second, is the TLS security handshake. A client sends a ClientHello to a server, it carries out some cryptographic operations and responds with a ServerHello containing a server certificate. The client verifies the certificate, confirms the handshake and sends application traffic such as an HTTP request.</p><p><a href="https://datatracker.ietf.org/doc/html/rfc9000#section-7"><u>QUIC</u></a> follows a similar process, however the sequence is shorter because the transport and security handshake is combined. A client sends an Initial packet containing a ClientHello to a server, it carries out some cryptographic operations and responds with an Initial packet containing a ServerHello with a server certificate. The client verifies the certificate and then sends application data.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7wsMcFwy8xMRYwQyFNm6oC/5d131543e7704794776dfc3ed89c1693/image2.png" />
          </figure><p>The QUIC handshake does not require client IP address validation before starting the security handshake. This means there is a risk that an attacker could spoof a client IP and cause a server to do cryptographic work and send data to a target victim IP (aka a <a href="https://blog.cloudflare.com/reflections-on-reflections/"><u>reflection attack</u></a>). <a href="https://datatracker.ietf.org/doc/html/rfc9000"><u>RFC 9000</u></a> is careful to describe the risks this poses and provides mechanisms to reduce them (for example, see Sections <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-8"><u>8</u></a> and <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-9.3.1"><u>9.3.1</u></a>). Until a client address is verified, a server employs an anti-amplification limit, sending a maximum of 3x as many bytes as it has received. Furthermore, a server can initiate address validation before engaging in the cryptographic handshake by responding with a <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-8.1.2"><u>Retry packet</u></a>. The retry mechanism, however, adds an additional round-trip to the QUIC handshake sequence, negating some of its benefits compared to TCP. Real-world QUIC deployments use a range of strategies and heuristics to detect traffic loads and enable different mitigations.</p><p>In order to understand how the researchers triggered an amplification attack despite these QUIC guardrails, we first need to dive into how IP broadcast works.</p>
    <div>
      <h3>Broadcast addresses</h3>
      <a href="#broadcast-addresses">
        
      </a>
    </div>
    <p>In Internet Protocol version 4 (IPv4) addressing, the final address in any given <a href="https://www.cloudflare.com/learning/network-layer/what-is-a-subnet/"><u>subnet</u></a> is a special broadcast IP address used to send packets to every node within the IP address range. Every node that is within the same subnet receives any packet that is sent to the broadcast address, enabling one sender to send a message that can be “heard” by potentially hundreds of adjacent nodes. This behavior is enabled by default in most network-connected systems and is critical for discovery of devices within the same IPv4 network.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/49zGjFbeIv7RxZMM6W2i5V/9e9e5f2f3bd8401467887d488930f476/image3.png" />
          </figure><p>The broadcast address by nature poses a risk of DDoS amplification; for every one packet sent, hundreds of nodes have to process the traffic. </p>
    <div>
      <h3>Dealing with the expected broadcast</h3>
      <a href="#dealing-with-the-expected-broadcast">
        
      </a>
    </div>
    <p>To combat the risk posed by broadcast addresses, by default most routers reject packets originating from outside their IP subnet which are targeted at the broadcast address of networks for which they are locally connected. Broadcast packets are only allowed to be forwarded within the same IP subnet, preventing attacks from the Internet from targeting servers across the world.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5TU3GO26KOJgzLHcS9Uxiu/6cd334afc3925b1713b7e706decc7269/image1.png" />
          </figure><p>The same techniques are not generally applied when a given router is not directly connected to a given subnet. So long as an address is not locally treated as a broadcast address, <a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/"><u>Border Gateway Protocol</u></a> (BGP) or other routing protocols will continue to route traffic from external IPs toward the last IPv4 address in a subnet. Essentially, this means a “broadcast address” is only relevant within a local scope of routers and hosts connected together via Ethernet. To routers and hosts across the Internet, a broadcast IP address is routed in the same way as any other IP.</p>
    <div>
      <h3>Binding IP address ranges to hosts</h3>
      <a href="#binding-ip-address-ranges-to-hosts">
        
      </a>
    </div>
    <p>Each Cloudflare server is expected to be capable of serving content from every website on the Cloudflare network. Because our network utilizes <a href="https://www.cloudflare.com/learning/cdn/glossary/anycast-network/"><u>Anycast</u></a> routing, each server necessarily needs to be listening on (and capable of returning traffic from) every Anycast IP address in use on our network.</p><p>To do so, we take advantage of the loopback interface on each server. Unlike a physical network interface, all IP addresses within a given IP address range are made available to the host (and will be processed locally by the kernel) when bound to the loopback interface.</p><p>The mechanism by which this works is straightforward. In a traditional routing environment, <a href="https://en.wikipedia.org/wiki/Longest_prefix_match"><u>longest prefix matching</u></a> is employed to select a route. Under longest prefix matching, routes towards more specific blocks of IP addresses (such as 192.0.2.96/29, a range of 8 addresses) will be selected over routes to less specific blocks of IP addresses (such as 192.0.2.0/24, a range of 256 addresses).</p><p>While Linux utilizes longest prefix matching, it consults an additional step — the Routing Policy Database (RPDB) — before immediately searching for a match. The RPDB contains a list of routing tables which can contain routing information and their individual priorities. The default RPDB looks like this:</p>
            <pre><code>$ ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default</code></pre>
            <p>Linux will consult each routing table in ascending numerical order to try and find a matching route. Once one is found, the search is terminated and the route immediately used.</p><p>If you’ve previously worked with routing rules on Linux, you are likely familiar with the contents of the main table. Contrary to the existence of the table named “default”, “main” generally functions as the default lookup table. It is also the one which contains what we traditionally associate with route table information:</p>
            <pre><code>$ ip route show table main
default via 192.0.2.1 dev eth0 onlink
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.2</code></pre>
            <p>This is, however, not the first routing table that will be consulted for a given lookup. Instead, that task falls to the local table:</p>
            <pre><code>$ ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.0.2.2 dev eth0 proto kernel scope host src 192.0.2.2
broadcast 192.0.2.255 dev eth0 proto kernel scope link src 192.0.2.2</code></pre>
            <p>Looking at the table, we see two new types of routes — local and broadcast. As their names would suggest, these routes dictate two distinctly different functions: routes that are handled locally and routes that will result in a packet being broadcast. Local routes provide the desired functionality — any prefix with a local route will have all IP addresses in the range processed by the kernel. Broadcast routes will result in a packet being broadcast to all IP addresses within the given range. Both types of routes are added automatically when an IP address is bound to an interface (and, when a range is bound to the loopback (lo) interface, the range itself will be added as a local route).</p>
    <div>
      <h3>Vulnerability discovery</h3>
      <a href="#vulnerability-discovery">
        
      </a>
    </div>
    <p>Deployments of QUIC are highly dependent on the load-balancing and packet forwarding infrastructure that they sit on top of. Although QUIC’s RFCs describe risks and mitigations, there can still be attack vectors depending on the nature of server deployments. The reporting researchers studied QUIC deployments across the Internet and discovered that sending a QUIC Initial packet to one of Cloudflare’s broadcast addresses triggered a flood of responses. The aggregate amount of response data exceeded the RFC's 3x amplification limit.</p><p>Taking a look at the local routing table of an example Cloudflare system, we see a potential culprit:</p>
            <pre><code>$ ip route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 192.0.2.2 dev eth0 proto kernel scope host src 192.0.2.2
broadcast 192.0.2.255 dev eth0 proto kernel scope link src 192.0.2.2
local 203.0.113.0 dev lo proto kernel scope host src 203.0.113.0
local 203.0.113.0/24 dev lo proto kernel scope host src 203.0.113.0
broadcast 203.0.113.255 dev lo proto kernel scope link src 203.0.113.0</code></pre>
            <p>On this example system, the anycast prefix 203.0.113.0/24 has been bound to the loopback interface (lo) through the use of standard tooling. Acting dutifully under the standards of IPv4, the tooling has assigned both special types of routes — a local one for the IP range itself and a broadcast one for the final address in the range — to the interface.</p><p>While traffic to the broadcast address of our router’s directly connected subnet is filtered as expected, broadcast traffic targeting our routed anycast prefixes still arrives at our servers themselves. Normally, broadcast traffic arriving at the loopback interface does little to cause problems. Services bound to a specific port across an entire range will receive data sent to the broadcast address and continue as normal. Unfortunately, this relatively simple trait breaks down when normal expectations are broken.</p><p>Cloudflare’s frontend consists of several worker processes, each of which independently binds to the entire anycast range on UDP port 443. In order to enable multiple processes to bind to the same port, we use the SO_REUSEPORT socket option. While SO_REUSEPORT <a href="https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/"><u>has additional benefits</u></a>, it also causes traffic sent to the broadcast address to be copied to every listener.</p><p>Each individual QUIC server worker operates in isolation. Each one reacted to the same client Initial, duplicating the work on the server side and generating response traffic to the client's IP address. Thus, a single packet could trigger a significant amplification. While specifics will vary by implementation, a typical one-listener-per-core stack (which sends retries in response to presumed timeouts) on a 128-core system could result in 384 replies being generated and sent for each packet sent to the broadcast address.</p><p>Although the researchers demonstrated this attack on QUIC, the underlying vulnerability can affect other UDP request/response protocols that use sockets in the same way.</p>
    <div>
      <h3>Mitigation</h3>
      <a href="#mitigation">
        
      </a>
    </div>
    <p>As a communication methodology, broadcast is not generally desirable for anycast prefixes. Thus, the easiest method to mitigate the issue was simply to disable broadcast functionality for the final address in each range.</p><p>Ideally, this would be done by modifying our tooling to only add the local routes in the local routing table, skipping the inclusion of the broadcast ones altogether. Unfortunately, the only practical mechanism to do so would involve patching and maintaining our own internal fork of the iproute2 suite, a rather heavy-handed solution for the problem at hand.</p><p>Instead, we decided to focus on removing the route itself. Similar to any other route, it can be removed using standard tooling:</p>
            <pre><code>$ sudo ip route del 203.0.113.255 table local</code></pre>
            <p>To do so at scale, we made a relatively minor change to our deployment system:</p>
            <pre><code>  {%- for lo_route in lo_routes %}
    {%- if lo_route.type == "broadcast" %}
        # All broadcast addresses are implicitly ipv4
        {%- do remove_route({
        "dev": "lo",
        "dst": lo_route.dst,
        "type": "broadcast",
        "src": lo_route.src,
        }) %}
    {%- endif %}
  {%- endfor %}</code></pre>
            <p>In doing so, we effectively ensure that all broadcast routes attached to the loopback interface are removed, mitigating the risk by ensuring that the specification-defined broadcast address is treated no differently than any other address in the range.</p>
    <div>
      <h3>Next steps </h3>
      <a href="#next-steps">
        
      </a>
    </div>
    <p>While the vulnerability specifically affected broadcast addresses within our anycast range, it likely expands past our infrastructure. Anyone with infrastructure that meets the relatively narrow criteria (a multi-worker, multi-listener UDP-based service that is bound to all IP addresses on a machine with routable IP prefixes attached in such a way as to expose the broadcast address) will be affected unless mitigations are in place. We encourage network administrators and security professionals to assess their systems for configurations that may present a local amplification attack vector.</p> ]]></content:encoded>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Edge]]></category>
            <category><![CDATA[DDoS]]></category>
            <category><![CDATA[HTTP3]]></category>
            <category><![CDATA[Bug Bounty]]></category>
            <guid isPermaLink="false">6ZaxgQxDACeIF6MZAquLPV</guid>
            <dc:creator>Josephine Chow</dc:creator>
            <dc:creator>June Slater</dc:creator>
            <dc:creator>Bryton Herdes</dc:creator>
            <dc:creator>Lucas Pardue</dc:creator>
        </item>
        <item>
            <title><![CDATA[Multi-Path TCP: revolutionizing connectivity, one path at a time]]></title>
            <link>https://blog.cloudflare.com/multi-path-tcp-revolutionizing-connectivity-one-path-at-a-time/</link>
            <pubDate>Fri, 03 Jan 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ Multi-Path TCP (MPTCP) leverages multiple network interfaces, like Wi-Fi and cellular, to provide seamless mobility for more reliable connectivity. While promising, MPTCP is still in its early stages, ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Internet is designed to provide multiple paths between two endpoints. Attempts to exploit multi-path opportunities are almost as old as the Internet, culminating in <a href="https://datatracker.ietf.org/doc/html/rfc2991"><u>RFCs</u></a> documenting some of the challenges. Still, today, virtually all end-to-end communication uses only one available path at a time. Why? It turns out that in multi-path setups, even the smallest differences between paths can harm the connection quality due to <a href="https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing#History"><u>packet reordering</u></a> and other issues. As a result, Internet devices usually use a single path and let the routers handle the path selection.</p><p>There is another way. Enter Multi-Path TCP (MPTCP), which exploits the presence of multiple interfaces on a device, such as a mobile phone that has both Wi-Fi and cellular antennas, to achieve multi-path connectivity.</p><p>MPTCP has had a long history — see the <a href="https://en.wikipedia.org/wiki/Multipath_TCP"><u>Wikipedia article</u></a> and the <a href="https://datatracker.ietf.org/doc/html/rfc8684"><u>spec (RFC 8684)</u></a> for details. It's a major extension to the TCP protocol, and historically most of the TCP changes failed to gain traction. However, MPTCP is supposed to be mostly an operating system feature, making it easy to enable. Applications should only need minor code changes to support it.</p><p>There is a caveat, however: MPTCP is still fairly immature, and while it can use multiple paths, giving it superpowers over regular TCP, it's not always strictly better than it. Whether MPTCP should be used over TCP is really a case-by-case basis.</p><p>In this blog post we show how to set up MPTCP to find out.</p>
    <div>
      <h2>Subflows</h2>
      <a href="#subflows">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3r8AP5BHbvtYEtXmYSXFwO/36e95cbac93cdecf2f5ee65945abf0b3/Screenshot_2024-12-23_at_3.07.37_PM.png" />
          </figure><p>Internally, MPTCP extends TCP by introducing "subflows". When everything is working, a single TCP connection can be backed by multiple MPTCP subflows, each using different paths. This is a big deal - a single TCP byte stream is now no longer identified by a single 5-tuple. On Linux you can see the subflows with <code>ss -M</code>, like:</p>
            <pre><code>marek$ ss -tMn dport = :443 | cat
tcp   ESTAB 0  	0 192.168.2.143%enx2800af081bee:57756 104.28.152.1:443
tcp   ESTAB 0  	0       192.168.1.149%wlp0s20f3:44719 104.28.152.1:443
mptcp ESTAB 0  	0                 192.168.2.143:57756 104.28.152.1:443</code></pre>
            <p>Here you can see a single MPTCP connection, composed of two underlying TCP flows.</p>
    <div>
      <h2>MPTCP aspirations</h2>
      <a href="#mptcp-aspirations">
        
      </a>
    </div>
    <p>Being able to separate the lifetime of a connection from the lifetime of a flow allows MPTCP to address two problems present in classical TCP: aggregation and mobility.</p><ul><li><p><b>Aggregation</b>: MPTCP can aggregate the bandwidth of many network interfaces. For example, in a data center scenario, it's common to use interface bonding. A single flow can make use of just one physical interface. MPTCP, by being able to launch many subflows, can expose greater overall bandwidth. I'm personally not convinced if this is a real problem. As we'll learn below, modern Linux has a <a href="https://dl.ifip.org/db/conf/networking/networking2016/1570234725.pdf"><u>BLESS-like MPTCP scheduler</u></a> and macOS stack has the "aggregation" mode, so aggregation should work, but I'm not sure how practical it is. However, there are <a href="https://www.openmptcprouter.com/"><u>certainly projects that are trying to do link aggregation</u></a> using MPTCP.</p></li><li><p><b>Mobility</b>: On a customer device, a TCP stream is typically broken if the underlying network interface goes away. This is not an uncommon occurrence — consider a smartphone dropping from Wi-Fi to cellular. MPTCP can fix this — it can create and destroy many subflows over the lifetime of a single connection and survive multiple network changes.</p></li></ul><p>Improving reliability for mobile clients is a big deal. While some software can use QUIC, which also works on <a href="https://www.ietf.org/archive/id/draft-ietf-quic-multipath-11.html"><u>Multipath Extensions</u></a>, a large number of classical services still use TCP. A great example is SSH: it would be very nice if you could walk around with a laptop and keep an SSH session open and switch Wi-Fi networks seamlessly, without breaking the connection.</p><p>MPTCP work was initially driven by <a href="https://uclouvain.be/fr/index.html"><u>UCLouvain in Belgium</u></a>. The first serious adoption was on the iPhone. Apparently, users have a tendency to use Siri while they are walking out of their home. It's very common to lose Wi-Fi connectivity while they are doing this. (<a href="https://youtu.be/BucQ1lfbtd4?t=533"><u>source</u></a>) </p>
    <div>
      <h2>Implementations</h2>
      <a href="#implementations">
        
      </a>
    </div>
    <p>Currently, there are only two major MPTCP implementations — Linux kernel support from v5.6, but realistically you need at least kernel v6.1 (<a href="https://oracle.github.io/kconfigs/?config=UTS_RELEASE&amp;config=MPTCP"><u>MPTCP is not supported on Android</u></a> yet) and iOS from version 7 / Mac OS X from 10.10.</p><p>Typically, Linux is used on the server side, and iOS/macOS as the client. It's possible to get Linux to work as a client-side, but it's not straightforward, as we'll learn soon. Beware — there is plenty of outdated Linux MPTCP documentation. The code has had a bumpy history and at least two different APIs were proposed. See the Linux kernel source for <a href="https://docs.kernel.org/networking/mptcp.html"><u>the mainline API</u></a> and the <a href="https://www.mptcp.dev/"><u>mptcp.dev</u></a> website.</p>
    <div>
      <h2>Linux as a server</h2>
      <a href="#linux-as-a-server">
        
      </a>
    </div>
    <p>Conceptually, the MPTCP design is pretty sensible. After the initial TCP handshake, each peer may announce additional addresses (and ports) on which it can be reached. There are two ways of doing this. First, in the handshake TCP packet each peer specifies the "<i>Do not attempt to establish new subflows to this address and port</i>" bit, also known as bit [C], in the MPTCP TCP extensions header.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/bT8oz3wxpw7alftvdYg5n/b7614a4d10b6c81e18027f6785391ede/BLOG-2637_3.png" />
          </figure><p><sup><i>Wireshark dissecting MPTCP flags from a SYN packet. </i></sup><a href="https://github.com/multipath-tcp/mptcp_net-next/issues/535"><sup><i><u>Tcpdump does not report</u></i></sup></a><sup><i> this flag yet.</i></sup></p><p>With this bit cleared, the other peer is free to assume the two-tuple is fine to be reconnected to. Typically, the <b>server allows</b> the client to reuse the server IP/port address. Usually, the <b>client is not listening</b> and disallows the server to connect back to it. There are caveats though. For example, in the context of Cloudflare, where our servers are using Anycast addressing, reconnecting to the server IP/port won't work. Going twice to the IP/port pair is unlikely to reach the same server. For us it makes sense to set this flag, disallowing clients from reconnecting to our server addresses. This can be done on Linux with:</p>
            <pre><code># Linux server sysctl - useful for ECMP or Anycast servers
$ sysctl -w net.mptcp.allow_join_initial_addr_port=0
</code></pre>
            <p>There is also a second way to advertise a listening IP/port. During the lifetime of a connection, a peer can send an ADD-ADDR MPTCP signal which advertises a listening IP/port. This can be managed on Linux by <code>ip mptcp endpoint ... signal</code>, like:</p>
            <pre><code># Linux server - extra listening address
$ ip mptcp endpoint add 192.51.100.1 dev eth0 port 4321 signal
</code></pre>
            <p>With such a config, a Linux peer (typically server) will report the additional IP/port with ADD-ADDR MPTCP signal in an ACK packet, like this:</p>
            <pre><code>host &gt; host: Flags [.], ack 1, win 8, options [mptcp 30 add-addr v1 id 1 192.51.100.1:4321 hmac 0x...,nop,nop], length 0
</code></pre>
            <p>It's important to realize that either peer can send ADD-ADDR messages. Unusual as it might sound, it's totally fine for the client to advertise extra listening addresses. The most common scenario though, consists of either nobody, or just a server, sending ADD-ADDR.</p><p>Technically, to launch an MPTCP socket on Linux, you just need to replace IPPROTO_TCP with IPPROTO_MPTCP in the application code:</p>
            <pre><code>IPPROTO_MPTCP = 262
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP)
</code></pre>
            <p>In practice, though, this introduces some changes to the sockets API. Currently not all setsockopt's work yet — like <code>TCP_USER_TIMEOUT</code>. Additionally, at this stage, MPTCP is incompatible with kTLS.</p>
    <div>
      <h2>Path manager / scheduler</h2>
      <a href="#path-manager-scheduler">
        
      </a>
    </div>
    <p>Once the peers have exchanged the address information, MPTCP is ready to kick in and perform the magic. There are two independent pieces of logic that MPTCP handles. First, given the address information, MPTCP must figure out if it should establish additional subflows. The component that decides on this is called "Path Manager". Then, another component called "scheduler" is responsible for choosing a specific subflow to transmit the data over.</p><p>Both peers have a path manager, but typically only the client uses it. A path manager has a hard task to launch enough subflows to get the benefits, but not too many subflows which could waste resources. This is where the MPTCP stacks get complicated. </p>
    <div>
      <h2>Linux as client</h2>
      <a href="#linux-as-client">
        
      </a>
    </div>
    <p>On Linux, path manager is an operating system feature, not an application feature. The in-kernel path manager requires some configuration — it must know which IP addresses and interfaces are okay to start new subflows. This is configured with <code>ip mptcp endpoint ... subflow</code>, like:</p>
            <pre><code>$ ip mptcp endpoint add dev wlp1s0 192.0.2.3 subflow  # Linux client
</code></pre>
            <p>This informs the path manager that we (typically a client) own a 192.0.2.3 IP address on interface wlp1s0, and that it's fine to use it as source of a new subflow. There are two additional flags that can be passed here: "backup" and "fullmesh". Maintaining these <code>ip mptcp endpoints</code> on a client is annoying. They need to be added and removed every time networks change. Fortunately, <a href="https://ubuntu.com/core/docs/networkmanager"><u>NetworkManager</u></a> from 1.40 supports managing these by default. If you want to customize the "backup" or "fullmesh" flags, you can do this here (see <a href="https://networkmanager.dev/docs/api/1.44.4/settings-connection.html#:~:text=mptcp-flags"><u>the documentation</u></a>):</p>
            <pre><code>ubuntu$ cat /etc/NetworkManager/conf.d/95-mptcp.conf
# set "subflow" on all managed "ip mptcp endpoints". 0x22 is the default.
[connection]
connection.mptcp-flags=0x22
</code></pre>
            <p>Path manager also takes a "limit" setting, to set a cap of additional subflows per MPTCP connection, and limit the received ADD-ADDR messages, like: </p>
            <pre><code>$ ip mptcp limits set subflow 4 add_addr_accepted 2  # Linux client
</code></pre>
            <p>I experimented with the "mobility" use case on my Ubuntu 22 Linux laptop. I repeatedly enabled and disabled Wi-Fi and Ethernet. On new kernels (v6.12), it works, and I was able to hold a reliable MPTCP connection over many interface changes. I was <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/534"><u>less lucky with the Ubuntu v6.8</u></a> kernel. Unfortunately, the <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/536"><u>default path manager on Linux</u></a> client only works when the flag "<i>Do not attempt to establish new subflows to this address and port</i>" is cleared on the server. Server-announced ADD-ADDR don't result in new subflows created, unless <code>ip mptcp endpoint</code> has a <code>fullmesh</code> flag.</p><p>It feels like the underlying MPTCP transport code works, but the path manager requires a bit more intelligence. With a new kernel, it's possible to get the "interactive" case working out of the box, but not for the ADD-ADDR case. </p>
    <div>
      <h2>Custom path manager</h2>
      <a href="#custom-path-manager">
        
      </a>
    </div>
    <p>Linux allows for two implementations of a path manager component. It can either use built-in kernel implementation (default), or userspace netlink daemon.</p>
            <pre><code>$ sysctl -w net.mptcp.pm_type=1 # use userspace path manager
</code></pre>
            <p>However, from what I found there is no serious implementation of configurable userspace path manager. The existing <a href="https://github.com/multipath-tcp/mptcpd/blob/main/plugins/path_managers/sspi.c"><u>implementations don't do much</u></a>, and the API <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/533"><u>seems</u></a> <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/532"><u>immature</u></a> yet.</p>
    <div>
      <h2>Scheduler and BPF extensions</h2>
      <a href="#scheduler-and-bpf-extensions">
        
      </a>
    </div>
    <p>Thus far we've covered Path Manager, but what about the scheduler that chooses which link to actually use? It seems that on Linux there is only one built-in "default" scheduler, and it can do basic failover on packet loss. The developers want to write <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/75"><u>MPTCP schedulers in BPF</u></a>, and this work is in-progress.</p>
    <div>
      <h2>macOS</h2>
      <a href="#macos">
        
      </a>
    </div>
    <p>As opposed to Linux, macOS and iOS expose a raw MPTCP API. On those operating systems, path manager is not handled by the kernel, but instead can be an application responsibility. The exposed low-level API is based on <code>connectx()</code>. For example, <a href="https://github.com/apple-oss-distributions/network_cmds/blob/97bfa5b71464f1286b51104ba3e60db78cd832c9/mptcp_client/mptcp_client.c#L461"><u>here's an example of obscure code</u></a> that establishes one connection with two subflows:</p>
            <pre><code>int sock = socket(AF_MULTIPATH, SOCK_STREAM, 0);
connectx(sock, ..., &amp;cid1);
connectx(sock, ..., &amp;cid2);
</code></pre>
            <p>This powerful API is hard to use though, as it would require every application to listen for network changes. Fortunately, macOS and iOS also expose higher-level APIs. One <a href="https://github.com/mptcp-apps/mptcp-hello/blob/main/c/macOS/main.c"><u>example is nw_connection</u></a> in C, which uses nw_parameters_set_multipath_service.</p><p>Another, more common example is using <code>Network.framework</code>, and would <a href="https://gist.github.com/majek/cb54b537c74506164d2a7fa2d6601491"><u>look like this</u></a>:</p>
            <pre><code>let parameters = NWParameters.tcp
parameters.multipathServiceType = .interactive
let connection = NWConnection(host: host, port: port, using: parameters) 
</code></pre>
            <p>The API supports three MPTCP service type modes:</p><ul><li><p><i>Handover Mode</i>: Tries to minimize cellular. Uses only Wi-Fi. Uses cellular only when <a href="https://support.apple.com/en-us/102228"><u>Wi-Fi Assist</u></a> is enabled and makes such a decision.</p></li><li><p><i>Interactive Mode</i>: Used for Siri. Reduces latency. Only for low-bandwidth flows.</p></li><li><p><i>Aggregation Mode</i>: Enables resource pooling but it's only available for developer accounts and not deployable.</p></li></ul>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/47MukOs6bhCMOkO1JL15sP/7dd75417b855b681bde504122d5af01e/Screenshot_2024-12-23_at_2.59.51_PM.png" />
          </figure><p>The MPTCP API is nicely integrated with the <a href="https://support.apple.com/en-us/102228"><u>iPhone "Wi-Fi Assist" feature</u></a>. While the official documentation is lacking, it's possible to find <a href="https://youtu.be/BucQ1lfbtd4?t=533"><u>sources explaining</u></a> how it actually works. I was able to successfully test both the cleared "<i>Do not attempt to establish new subflows"</i> bit and ADD-ADDR scenarios. Hurray!</p>
    <div>
      <h2>IPv6 caveat</h2>
      <a href="#ipv6-caveat">
        
      </a>
    </div>
    <p>Sadly, MPTCP IPv6 has a caveat. Since IPv6 addresses are long, and MPTCP uses the space-constrained TCP Extensions field, there is <a href="https://github.com/multipath-tcp/mptcp_net-next/issues/448"><u>not enough room for ADD-ADDR messages</u></a> if TCP timestamps are enabled. If you want to use MPTCP and IPv6, it's something to consider.</p>
    <div>
      <h2>Summary</h2>
      <a href="#summary">
        
      </a>
    </div>
    <p>I find MPTCP very exciting, being one of a few deployable serious TCP extensions. However, current implementations are limited. My experimentation showed that the only practical scenario where currently MPTCP might be useful is:</p><ul><li><p>Linux as a server</p></li><li><p>macOS/iOS as a client</p></li><li><p>"interactive" use case</p></li></ul><p>With a bit of effort, Linux can be made to work as a client.</p><p>Don't get me wrong, <a href="https://netdevconf.info/0x14/pub/slides/59/mptcp-netdev0x14-final.pdf"><u>Linux developers did tremendous work</u></a> to get where we are, but, in my opinion for any serious out-of-the-box use case, we're not there yet. I'm optimistic that Linux can develop a good MPTCP client story relatively soon, and the possibility of implementing the Path manager and Scheduler in BPF is really enticing. </p><p>Time will tell if MPTCP succeeds — it's been 15 years in the making. In the meantime, <a href="https://datatracker.ietf.org/meeting/121/materials/slides-121-quic-multipath-quic-00"><u>Multi-Path QUIC</u></a> is under active development, but it's even further from being usable at this stage.</p><p>We're not quite sure if it makes sense for Cloudflare to support MPTCP. <a href="https://community.cloudflare.com/c/feedback/feature-request/30"><u>Reach out</u></a> if you have a use case in mind!</p><p><i>Shoutout to </i><a href="https://fosstodon.org/@matttbe"><i><u>Matthieu Baerts</u></i></a><i> for tremendous help with this blog post.</i></p> ]]></content:encoded>
            <category><![CDATA[TCP]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Linux]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <guid isPermaLink="false">6ZxrGIedGqREgTs02vpt0t</guid>
            <dc:creator>Marek Majkowski</dc:creator>
        </item>
        <item>
            <title><![CDATA[Network performance update: Security Week 2024]]></title>
            <link>https://blog.cloudflare.com/network-performance-update-security-week-2024/</link>
            <pubDate>Fri, 08 Mar 2024 14:00:27 GMT</pubDate>
            <description><![CDATA[ Cloudflare is the fastest provider in 44% of networks around the world for 95th percentile connection time. Let’s dig into the data and talk about how we do it ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6cJ3Liy6bLspNaws7lwGNu/e22370f578e9d7219efe7e6e69426621/image3-23.png" />
            
            </figure><p>We constantly measure our own network’s performance against other networks, look for ways to improve our performance compared to them, and share the results of our efforts. Since <a href="/benchmarking-edge-network-performance/">June 2021</a>, we’ve been sharing benchmarking results we’ve run against other networks to see how we compare.</p><p>In this post we are going to share the most recent updates since our last post <a href="/network-performance-update-birthday-week-2023">in September</a>, and talk about how we are getting as fast as we are.</p>
    <div>
      <h3>How we stack up</h3>
      <a href="#how-we-stack-up">
        
      </a>
    </div>
    <p>Since <a href="/benchmarking-edge-network-performance/">June 2021</a>, we’ve been taking a close look at the most reported eyeball-facing ISPs and taking actions for the specific networks where we have some room for improvement. Cloudflare was already the fastest provider for TCP Connection time at the 95th percentile for 44% of the networks around the world (we define a network as country and AS number pair). We chose this metric to show how our network helps make your websites faster by getting you to where your customers are. Taking a look at the numbers, in July 2022, Cloudflare was ranked #1 in 33% of the networks and was within 2 ms (95th percentile TCP Connection Time) or 5% of the #1 provider for 8% of the networks that we measured. For reference, our closest competitor was the fastest for 20% of networks.</p><p>As of August 30, 2023, Cloudflare was the fastest provider for 44% of networks — and was within 2 ms (95th percentile TCP Connection Time) or 5% of the fastest provider for 10% of the networks that we measured—whereas our closest competitor (Amazon Cloudfront) was the fastest for 19% of networks. As of February 15, 2024, we are still #1 in 44% of networks for 95th percentile TCP Connection Time. Let’s dig into the data.</p>
    <div>
      <h3>Lightning fast</h3>
      <a href="#lightning-fast">
        
      </a>
    </div>
    <p>Looking at 95th percentile TCP connect times from November 18, 2023, to February 15, 2024, Cloudflare is the #1 provider in 44% of the top 1000 networks:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4MfvB63nPET2ddJEKCUsLV/621f6ff7f99d90217f9e8dc152e3c550/newplot--1-.png" />
            
            </figure><p>Our P95 TCP Connection time has been trending down since November, and we are consistently 50ms faster at P95 than our closest competitor (Amazon CloudFront):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7iEOyp7va70O2pmUaKC2Wq/f90af229b1b4802b82d44483cf8b4274/newplot--8-.png" />
            
            </figure>
<table>
<thead>
  <tr>
    <th><span>Connect time comparisons between providers at 50th and 95th percentile</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td></td>
    <td><span>P50 Connect (ms)</span></td>
    <td><span>P95 Connect (ms)</span></td>
  </tr>
  <tr>
    <td><span>Cloudflare</span></td>
    <td><span>130</span></td>
    <td><span>579</span></td>
  </tr>
  <tr>
    <td><span>Amazon</span></td>
    <td><span>145</span></td>
    <td><span>637</span></td>
  </tr>
  <tr>
    <td><span>Google</span></td>
    <td><span>190</span></td>
    <td><span>772</span></td>
  </tr>
  <tr>
    <td><span>Akamai</span></td>
    <td><span>195</span></td>
    <td><span>774</span></td>
  </tr>
  <tr>
    <td><span>Fastly</span></td>
    <td><span>189</span></td>
    <td><span>734</span></td>
  </tr>
</tbody>
</table><p>These graphs show that day over day, Cloudflare was consistently the fastest provider. They also show the gaps between Cloudflare and the other competitors.  When you look at the 95th percentile, Cloudflare is almost 200ms faster than Akamai across the world for connect times. This shows that our network reaches more places and allows users to get their content faster than Akamai on a consistent basis.</p><p>When we aggregate this data over the whole time period, Cloudflare is the fastest in the most networks. For that whole time span of November 18, 2023, to February 15, 2024, Cloudflare was number 1 in 73% of networks for mean TCP connection time:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4UYB4DoR5ofuP4BZ0ot81u/8346bb37f7715517845f549bde1aae30/pasted-image-0-4.png" />
            
            </figure><p>Looking at a map plotting by 95th percentile TCP connect time, Cloudflare is the fastest in the most countries, and you can see this by the fact that most of the map is orange:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2VVEWU1obl2v0XPIJT7xkE/16ad0dbb190c4b0032eaac4768c42c54/newplot--2-.png" />
            
            </figure><p>For comparison, here’s what the map looked like in September 2023:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/38I3OXnGpE7leREtf9g92w/589db6e68041d3fc5ee270a49d20d460/pasted-image-0--1--1.png" />
            
            </figure><p>These numbers show that we’re reducing the overall TCP connection time around the world while simultaneously staying ahead of the competition. Let’s talk about how we get these numbers and what we’re doing to make you even faster.</p>
    <div>
      <h3>Measuring What Matters</h3>
      <a href="#measuring-what-matters">
        
      </a>
    </div>
    <p>As a quick reminder, here’s how we get the data for our measurements: when users receive a Cloudflare-branded error page, we use Real User Measurements (RUM) and fetch a small file from Cloudflare, Akamai, Amazon CloudFront, Fastly, and Google Cloud CDN. Browsers around the world report the performance of those providers from the perspective of the end-user network they are on. The goal is to provide an accurate picture of where different providers are faster, and more importantly, where Cloudflare can improve. You can read more about the methodology in the <a href="/benchmarking-edge-network-performance/">original Speed Week blog post</a>.</p><p>Using the RUM data, we measure various performance metrics, such as TCP Connection Time, Time to First Byte (TTFB), and Time to Last Byte (TTLB), for ourselves and other providers.</p><p>If we only collect data from a browser when we return an error page, you could see how variable the data can get: if one network or website is having a problem in a certain country, that country could overreport, meaning those networks would be more highly weighted in the calculations because more users reported from that network during a given time period.</p><p>For example, if a lot of users connecting over a small Brazilian network were generating reports because their websites were throwing errors more frequently, that could make this small network look a lot bigger to us. This small network in Brazil could have as many reports as Claro, a major network in the region, despite them being totally different when you look at the number of subscribers.  If we only look at the networks that report to us the most, it could cause smaller networks with fewer subscribers to be treated as more important because of point-in-time error conditions.</p><p>This phenomenon could cause the networks we look at to change week over week. Going back to the Brazil example, if the website that was throwing a bunch of errors fixed their problem, and we no longer saw measurements from that network, they may not show up as a “most reported network” depending on when we look at the data. This means that the networks we look at to consider where we are fastest are dependent on which networks are sending us the most reports at any given time, which is not optimal if we’re trying to get faster in these networks. We need to be able to get a consistent signal on these networks to understand where we’re faster and where we’re not.</p><p>We’ve addressed this issue by creating a fixed list of the networks we want to look at. We did this by looking at <a href="https://stats.labs.apnic.net/aspop/">public stats</a> on user population by network and then comparing that with our sample sizes by network until we identified the 1000 networks we want to examine.  This ensures that day over day, the networks we look at are the same.</p><p>Now let’s talk about what makes us faster in more places than other networks: HTTP/3.</p>
    <div>
      <h3>Blazing fast speeds with HTTP/3</h3>
      <a href="#blazing-fast-speeds-with-http-3">
        
      </a>
    </div>
    <p>One reason why Cloudflare is the fastest in the most networks is because we’ve been leading the charge with adoption and usage of <a href="https://www.cloudflare.com/learning/performance/what-is-http3/">HTTP/3</a> on our platform.  HTTP/3 allows for faster connectivity behavior which means we can get connections established faster and get data flowing. HTTP/3 is currently used by around 31% of Internet traffic:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7s33L2h6voHjT9pZ3O8aev/dbde692a716bacfa4001b67bfaf5a431/pasted-image-0--2--1.png" />
            
            </figure><p>To show that HTTP/3 improves connection times, we looked at two different Cloudflare endpoints that these tests ran against: one with HTTP/3 enabled and one with HTTP/3 disabled. The performance difference between the two is night and day.  Here’s a table showing the performance difference for 95th percentile connect time between Cloudflare zones when one zone has HTTP/3 enabled:</p>
<table>
<thead>
  <tr>
    <th></th>
    <th><span>P50 connect (ms)</span></th>
    <th><span>P95 connect (ms)</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Cloudflare HTTP/3</span></td>
    <td><span>130</span></td>
    <td><span>579</span></td>
  </tr>
  <tr>
    <td><span>Cloudflare non-HTTP/3</span></td>
    <td><span>174</span></td>
    <td><span>695</span></td>
  </tr>
</tbody>
</table><p>At P95, Cloudflare is 116 ms faster for connection times when HTTP/3 is enabled. This performance gain helps us be the fastest in the most networks.</p><p>But why does HTTP/3 help make us faster? HTTP/3 allows for faster connection setup times, which lets us take greater advantage of our global network footprint to be the fastest in the most networks. HTTP/3 is built on top of the QUIC protocol, which multiplexes <a href="https://www.cloudflare.com/learning/ddos/glossary/user-datagram-protocol-udp/">UDP</a> packets to allow for parallel streams to be sent at the same time. This means that TLS encryption can happen in parallel with connection establishment, shortening the amount of time that is needed to set up a secure connection. Paired with Cloudflare’s network that is incredibly close to end-users, this makes for significant latency reductions on user Connect times. All major browsers have HTTP/3 enabled by default, so you too can realize these latency improvements by <a href="https://developers.cloudflare.com/speed/optimization/protocol/http3/">enabling HTTP/3</a> on your website today.</p>
    <div>
      <h3>What’s next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We’re sharing our updates on our journey to become #1 everywhere so that you can see what goes into running the fastest network in the world. From here, our plan is the same as always: identify where we’re slower, fix it, and then tell you how we’ve gotten faster.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Network Performance Update]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">3DF05BMZSKT5bTh4hVbouI</guid>
            <dc:creator>David Tuber</dc:creator>
        </item>
        <item>
            <title><![CDATA[Free network flow monitoring for all enterprise customers]]></title>
            <link>https://blog.cloudflare.com/free-network-monitoring-for-enterprise/</link>
            <pubDate>Thu, 07 Mar 2024 14:00:43 GMT</pubDate>
            <description><![CDATA[ Today, we’re excited to announce that a free version of Cloudflare’s network flow monitoring product, Magic Network Monitoring, is now available to all Enterprise Customers ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4JDYfP3P5eCvUA6t2OVQRW/9623c870e75e74e813cd0abc5a9b8da9/image1-24.png" />
            
            </figure><p>A key component of <a href="https://www.cloudflare.com/network-security/">effective corporate network security</a> is establishing end to end visibility across all traffic that flows through the network. Every network engineer needs a complete overview of their network traffic to confirm their security policies work, to identify new vulnerabilities, and to analyze any shifts in traffic behavior. Often, it’s difficult to build out effective network monitoring as teams struggle with problems like configuring and tuning data collection, managing storage costs, and analyzing traffic across multiple visibility tools.</p><p>Today, we’re excited to announce that a free version of Cloudflare’s <a href="https://www.cloudflare.com/network-services/solutions/network-monitoring-tools/">network flow monitoring</a> product, Magic Network Monitoring, is available to all Enterprise Customers. Every Enterprise Customer can configure Magic Network Monitoring and immediately improve their network visibility in as little as 30 minutes via our self-serve onboarding process.</p><p>Enterprise Customers can visit the <a href="https://www.cloudflare.com/network-services/products/magic-network-monitoring/">Magic Network Monitoring product page</a>, click “Talk to an expert”, and fill out the form. You’ll receive access within 24 hours of submitting the request. Over the next month, the free version of Magic Network Monitoring will be rolled out to all Enterprise Customers. The product will automatically be available by default without the need to submit a form.</p>
    <div>
      <h3>How it works</h3>
      <a href="#how-it-works">
        
      </a>
    </div>
    <p>Cloudflare customers can send their network flow data (either NetFlow or sFlow) from their routers to Cloudflare’s network edge.</p><p>Magic Network Monitoring will pick up this data, parse it, and instantly provide insights and analytics on your network traffic. These analytics include traffic volume overtime in bytes and packets, top protocols, sources, destinations, ports, and TCP flags.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6AZo6eGAZteqDAzTz8JSzc/83dd771696c34386f200144f95fb8207/image3-20.png" />
            
            </figure>
    <div>
      <h3>Dogfooding Magic Network Monitoring during the remediation of the Thanksgiving 2023 security incident</h3>
      <a href="#dogfooding-magic-network-monitoring-during-the-remediation-of-the-thanksgiving-2023-security-incident">
        
      </a>
    </div>
    <p>Let’s review a recent example of how Magic Network Monitoring improved Cloudflare’s own network security and traffic visibility during the <a href="/thanksgiving-2023-security-incident">Thanksgiving 2023 security incident</a>. Our security team needed a lightweight method to identify malicious packet characteristics in our core data center traffic. We monitored for any network traffic sourced from or destined to a list of ASNs associated with the bad actor. Our security team setup Magic Network Monitoring and established visibility into our first core data center within 24 hours of the project kick-off. Today, Cloudflare continues to use Magic Network Monitoring to monitor for traffic related to bad actors and to provide real time traffic analytics on more than 1 Tbps of core data center traffic.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/15lzmYJOViOw36MiEo7RR1/e3252df389014e6a52aad4eab6a78b7c/Screenshot-2024-03-07-at-10.55.47.png" />
            
            </figure><p><i>Magic Network Monitoring - Traffic Analytics</i></p>
    <div>
      <h3>Monitoring local network traffic from IoT devices</h3>
      <a href="#monitoring-local-network-traffic-from-iot-devices">
        
      </a>
    </div>
    <p>Magic Network Monitoring also improves visibility on any network traffic that doesn’t go through Cloudflare. Imagine that you’re a network engineer at ACME Corporation, and it’s your job to manage and troubleshoot IoT devices in a factory that are connected to the factory’s internal network. The traffic generated by these IoT devices doesn’t go through Cloudflare because it is destined to other devices and endpoints on the internal network. Nonetheless, you still need to establish network visibility into device traffic over time to monitor and troubleshoot the system.</p><p>To solve the problem, you configure a router or other network device to securely send encrypted traffic flow summaries to Cloudflare via an IPSec tunnel. Magic Network Monitoring parses the data, and instantly provides you with insights and analytics on your network traffic. Now, when an IoT device goes down, or a connection between IoT devices is unexpectedly blocked, you can analyze historical network traffic data in Magic Network Monitoring to speed up the troubleshooting process.</p>
    <div>
      <h3>Monitoring cloud network traffic</h3>
      <a href="#monitoring-cloud-network-traffic">
        
      </a>
    </div>
    <p>As <a href="https://www.cloudflare.com/learning/cloud/what-is-cloud-networking/">cloud networking</a> becomes increasingly prevalent, it is essential for enterprises to <a href="https://www.cloudflare.com/network-services/solutions/enterprise-network-security/">invest in visibility</a> across their cloud environments. Let’s say you’re responsible for monitoring and troubleshooting your corporation's cloud network operations which are spread across multiple public cloud providers. You need to improve visibility into your cloud network traffic to analyze and troubleshoot any unexpected traffic patterns like configuration drift that leads to an exposed network port.</p><p>To improve traffic visibility across different cloud environments, you can export cloud traffic flow logs from any virtual device that supports NetFlow or sFlow to Cloudflare. In the future, we are building support for native cloud VPC flow logs in conjunction with <a href="/introducing-magic-cloud-networking">Magic Cloud Networking</a>. Cloudflare will parse this traffic flow data and provide alerts plus analytics across all your cloud environments in a single pane of glass on the Cloudflare dashboard.</p>
    <div>
      <h3>Improve your security posture today in less than 30 minutes</h3>
      <a href="#improve-your-security-posture-today-in-less-than-30-minutes">
        
      </a>
    </div>
    <p>If you’re an existing Enterprise customer, and you want to improve your corporate network security, you can get started right away. Visit the <a href="https://www.cloudflare.com/network-services/products/magic-network-monitoring/">Magic Network Monitoring product page</a>, click “Talk to an expert”, and fill out the form. You’ll receive access within 24 hours of submitting the request. You can begin the self-serve onboarding tutorial, and start monitoring your first batch of network traffic in less than 30 minutes.</p><p>Over the next month, the free version of Magic Network Monitoring will be rolled out to all Enterprise Customers. The product will be automatically available by default without the need to submit a form.</p><p>If you’re interested in becoming an Enterprise Customer, and have more questions about Magic Network Monitoring, you can <a href="https://www.cloudflare.com/network-services/products/magic-network-monitoring/">talk with an expert</a>. If you’re a free customer, and you’re interested in testing a limited beta of Magic Network Monitoring, you can <a href="https://docs.google.com/forms/d/1umsmwHmXgMesP2t4wH94uVExHaT60tb5RTeawqR_9Cg/edit">fill out this form to request access</a>.</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Magic Network Monitoring]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Monitoring]]></category>
            <category><![CDATA[IoT]]></category>
            <category><![CDATA[Magic Transit]]></category>
            <category><![CDATA[Magic WAN]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <guid isPermaLink="false">5kxbpURa5uO3pOPgoXY9Ga</guid>
            <dc:creator>Chris Draper</dc:creator>
        </item>
        <item>
            <title><![CDATA[Magic Cloud Networking simplifies security, connectivity, and management of public clouds]]></title>
            <link>https://blog.cloudflare.com/introducing-magic-cloud-networking/</link>
            <pubDate>Wed, 06 Mar 2024 14:01:00 GMT</pubDate>
            <description><![CDATA[ Introducing Magic Cloud Networking, a new set of capabilities to visualize and automate cloud networks to give our customers secure, easy, and seamless connection to public cloud environments ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4EE4QTE18JtBWAk0XucBb2/818464eba98f9928bbfa7bfe179780d8/image5-5.png" />
            
            </figure><p>Today we are excited to announce Magic Cloud Networking, supercharged by <a href="https://www.cloudflare.com/press-releases/2024/cloudflare-enters-multicloud-networking-market-unlocks-simple-secure/">Cloudflare’s recent acquisition of Nefeli Networks</a>’ innovative technology. These new capabilities to visualize and automate cloud networks will give our customers secure, easy, and seamless connection to public cloud environments.</p><p>Public clouds offer organizations a scalable and on-demand IT infrastructure without the overhead and expense of running their own datacenter. <a href="https://www.cloudflare.com/learning/cloud/what-is-cloud-networking/">Cloud networking</a> is foundational to applications that have been migrated to the cloud, but is difficult to manage without automation software, especially when operating at scale across multiple cloud accounts. Magic Cloud Networking uses familiar concepts to provide a single interface that controls and unifies multiple cloud providers’ native network capabilities to create reliable, cost-effective, and secure cloud networks.</p><p>Nefeli’s approach to multi-cloud networking solves the problem of building and operating end-to-end networks within and across public clouds, allowing organizations to <a href="https://www.cloudflare.com/application-services/solutions/">securely leverage applications</a> spanning any combination of internal and external resources. Adding Nefeli’s technology will make it easier than ever for our customers to connect and protect their users, private networks and applications.</p>
    <div>
      <h2>Why is cloud networking difficult?</h2>
      <a href="#why-is-cloud-networking-difficult">
        
      </a>
    </div>
    <p>Compared with a traditional on-premises data center network, cloud networking promises simplicity:</p><ul><li><p>Much of the complexity of physical networking is abstracted away from users because the physical and ethernet layers are not part of the network service exposed by the cloud provider.</p></li><li><p>There are fewer control plane protocols; instead, the cloud providers deliver a simplified <a href="https://www.cloudflare.com/learning/network-layer/what-is-sdn/">software-defined network (SDN)</a> that is fully programmable via API.</p></li><li><p>There is capacity — from zero up to very large — available instantly and on-demand, only charging for what you use.</p></li></ul><p>However, that promise has not yet been fully realized. Our customers have described several reasons cloud networking is difficult:</p><ul><li><p><b>Poor end-to-end visibility</b>: Cloud network visibility tools are difficult to use and silos exist even within single cloud providers that impede end-to-end monitoring and troubleshooting.</p></li><li><p><b>Faster pace</b>: Traditional IT management approaches clash with the promise of the cloud: instant deployment available on-demand. Familiar ClickOps and CLI-driven procedures must be replaced by automation to meet the needs of the business.</p></li><li><p><b>Different technology</b>: Established network architectures in on-premises environments do not seamlessly transition to a public cloud. The missing ethernet layer and advanced control plane protocols were critical in many network designs.</p></li><li><p><b>New cost models</b>: The dynamic pay-as-you-go usage-based cost models of the public clouds are not compatible with established approaches built around fixed cost circuits and 5-year depreciation. Network solutions are often architected with financial constraints, and accordingly, different architectural approaches are sensible in the cloud.</p></li><li><p><b>New security risks</b>: Securing public clouds with true <a href="https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/">zero trust</a> and least-privilege demands mature operating processes and automation, and familiarity with cloud-specific policies and IAM controls.</p></li><li><p><b>Multi-vendor:</b> Oftentimes enterprise networks have used single-vendor sourcing to facilitate interoperability, operational efficiency, and targeted hiring and training. Operating a network that extends beyond a single cloud, into other clouds or on-premises environments, is a multi-vendor scenario.</p></li></ul><p>Nefeli considered all these problems and the tensions between different customer perspectives to identify where the problem should be solved.</p>
    <div>
      <h2>Trains, planes, and automation</h2>
      <a href="#trains-planes-and-automation">
        
      </a>
    </div>
    <p>Consider a train system. To operate effectively it has three key layers:</p><ul><li><p>tracks and trains</p></li><li><p>electronic signals</p></li><li><p>a company to manage the system and sell tickets.</p></li></ul><p>A train system with good tracks, trains, and signals could still be operating below its full potential because its agents are unable to keep up with passenger demand. The result is that passengers cannot plan itineraries or purchase tickets.</p><p>The train company eliminates bottlenecks in process flow by simplifying the schedules, simplifying the pricing, providing agents with better booking systems, and installing automated ticket machines. Now the same fast and reliable infrastructure of tracks, trains, and signals can be used to its full potential.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/342dyvSqIvF0hJJoCDyf0I/8e92b93f922412344fa34cbbea7a4be1/image8.png" />
            
            </figure>
    <div>
      <h3>Solve the right problem</h3>
      <a href="#solve-the-right-problem">
        
      </a>
    </div>
    <p>In networking, there are an analogous set of three layers, called the <a href="https://www.cloudflare.com/learning/network-layer/what-is-the-control-plane/">networking planes</a>:</p><ul><li><p><b>Data Plane:</b> the network paths that transport data (in the form of packets) from source to destination.</p></li><li><p><b>Control Plane:</b> protocols and logic that change how packets are steered across the data plane.</p></li><li><p><b>Management Plane:</b> the configuration and monitoring interfaces for the data plane and control plane.</p></li></ul><p>In public cloud networks, these layers map to:</p><ul><li><p><b>Cloud Data Plane:</b> The underlying cables and devices are exposed to users as the <a href="https://www.cloudflare.com/learning/cloud/what-is-a-virtual-private-cloud/">Virtual Private Cloud (VPC)</a> or Virtual Network (VNet) service that includes subnets, routing tables, security groups/ACLs and additional services such as load-balancers and VPN gateways.</p></li><li><p><b>Cloud Control Plane:</b> In place of distributed protocols, the cloud control plane is a <a href="https://www.cloudflare.com/learning/network-layer/what-is-sdn/">software defined network (SDN)</a> that, for example, programs static route tables. (There is limited use of traditional control plane protocols, such as BGP to interface with external networks and ARP to interface with VMs.)</p></li><li><p><b>Cloud Management Plane:</b> An administrative interface with a UI and API which allows the admin to fully configure the data and control planes. It also provides a variety of monitoring and logging capabilities that can be enabled and integrated with 3rd party systems.</p></li></ul><p>Like our train example, most of the problems that our customers experience with cloud networking are in the third layer: the management plane.</p><p>Nefeli simplifies, unifies, and automates cloud network management and operations.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/nb9xcqGaRRaYIe0lvlbIs/83da6094ec1f7bc3e4a7d72a17fc511c/image2-6.png" />
            
            </figure>
    <div>
      <h3>Avoid cost and complexity</h3>
      <a href="#avoid-cost-and-complexity">
        
      </a>
    </div>
    <p>One common approach to tackle management problems in cloud networks is introducing Virtual Network Functions (VNFs), which are <a href="https://www.cloudflare.com/learning/cloud/what-is-a-virtual-machine/">virtual machines (VMs)</a> that do packet forwarding, in place of native cloud data plane constructs. Some VNFs are routers, firewalls, or load-balancers ported from a traditional network vendor’s hardware appliances, while others are software-based proxies often built on open-source projects like NGINX or Envoy. Because VNFs mimic their physical counterparts, IT teams could continue using familiar management tooling, but VNFs have downsides:</p><ul><li><p>VMs do not have custom network silicon and so instead rely on raw compute power. The VM is sized for the peak anticipated load and then typically runs 24x7x365. This drives a high cost of compute regardless of the actual utilization.</p></li><li><p>High-availability (HA) relies on fragile, costly, and complex network configuration.</p></li><li><p>Service insertion — the configuration to put a VNF into the packet flow — often forces packet paths that incur additional bandwidth charges.</p></li><li><p>VNFs are typically licensed similarly to their on-premises counterparts and are expensive.</p></li><li><p>VNFs lock in the enterprise and potentially exclude them benefitting from improvements in the cloud’s native data plane offerings.</p></li></ul><p>For these reasons, enterprises are turning away from VNF-based solutions and increasingly looking to rely on the native network capabilities of their cloud service providers. The built-in public cloud networking is elastic, performant, robust, and priced on usage, with high-availability options integrated and backed by the cloud provider’s service level agreement.</p><p>In our train example, the tracks and trains are good. Likewise, the cloud network data plane is highly capable. Changing the data plane to solve management plane problems is the wrong approach. To make this work at scale, organizations need a solution that works together with the native network capabilities of cloud service providers.</p><p>Nefeli leverages native cloud data plane constructs rather than third party VNFs.</p>
    <div>
      <h2>Introducing Magic Cloud Networking</h2>
      <a href="#introducing-magic-cloud-networking">
        
      </a>
    </div>
    <p>The Nefeli team has joined Cloudflare to integrate cloud network management functionality with Cloudflare One. This capability is called Magic Cloud Networking and with it, enterprises can use the Cloudflare dashboard and API to manage their public cloud networks and connect with Cloudflare One.</p>
    <div>
      <h3>End-to-end</h3>
      <a href="#end-to-end">
        
      </a>
    </div>
    <p>Just as train providers are focused only on completing train journeys in their own network, cloud service providers deliver network connectivity and tools within a single cloud account. Many large enterprises have hundreds of cloud accounts across multiple cloud providers. In an end-to-end network this creates disconnected networking silos which introduce operational inefficiencies and risk.</p><p>Imagine you are trying to organize a train journey across Europe, and no single train company serves both your origin and destination. You know they all offer the same basic service: a seat on a train. However, your trip is difficult to arrange because it involves multiple trains operated by different companies with their own schedules and ticketing rates, all in different languages!</p><p>Magic Cloud Networking is like an online travel agent that aggregates multiple transportation options, books multiple tickets, facilitates changes after booking, and then delivers travel status updates.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4P7EhpKlEfTnU7WdPq4dt6/4de908c385b406a89c97f4dc274b3acb/image6.png" />
            
            </figure><p>Through the Cloudflare dashboard, you can discover all of your network resources across accounts and cloud providers and visualize your end-to-end network in a single interface. Once Magic Cloud Networking discovers your networks, you can build a scalable network through a fully automated and simple workflow.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2qXuFK0Q1q96NtH0FYRNg0/3c449510b24a3f206b63b01e1799dddd/image3-8.png" />
            
            </figure><p><i>Resource inventory shows all configuration in a single and responsive UI</i></p>
    <div>
      <h3>Taming per-cloud complexity</h3>
      <a href="#taming-per-cloud-complexity">
        
      </a>
    </div>
    <p>Public clouds are used to deliver applications and services. Each cloud provider offers a composable stack of modular building blocks (resources) that start with the foundation of a billing account and then add on security controls. The next foundational layer, for server-based applications, is VPC networking. Additional resources are built on the VPC network foundation until you have compute, storage, and network infrastructure to host the enterprise application and data. Even relatively simple architectures can be composed of hundreds of resources.</p><p>The trouble is, these resources expose abstractions that are different from the building blocks you would use to build a service on prem, the abstractions differ between cloud providers, and they form a web of dependencies with complex rules about how configuration changes are made (rules which differ between resource types and cloud providers). For example, say I create 100 VMs, and connect them to an IP network. Can I make changes to the IP network while the VMs are using the network? The answer: it depends.</p><p>Magic Cloud Networking handles these differences and complexities for you. It configures native cloud constructs such as VPN gateways, routes, and security groups to securely connect your cloud VPC network to Cloudflare One without having to learn each cloud’s incantations for creating VPN connections and hubs.</p>
    <div>
      <h3>Continuous, coordinated automation</h3>
      <a href="#continuous-coordinated-automation">
        
      </a>
    </div>
    <p>Returning to our train system example, what if the railway maintenance staff find a dangerous fault on the railroad track? They manually set the signal to a stop light to prevent any oncoming trains using the faulty section of track. Then, what if, by unfortunate coincidence, the scheduling office is changing the signal schedule, and they set the signals remotely which clears the safety measure made by the maintenance crew? Now there is a problem that no one knows about and the root cause is that multiple authorities can change the signals via different interfaces without coordination.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/VNaeoX2TNwYwZsweytYSZ/40806d02108119204f638ed5f111d5d0/image1-10.png" />
            
            </figure><p>The same problem exists in cloud networks: configuration changes are made by different teams using different automation and configuration interfaces across a spectrum of roles such as billing, support, security, networking, firewalls, database, and application development.</p><p>Once your network is deployed, Magic Cloud Networking monitors its configuration and health, enabling you to be confident that the security and connectivity you put in place yesterday is still in place today. It tracks the cloud resources it is responsible for, automatically reverting drift if they are changed out-of-band, while allowing you to manage other resources, like storage buckets and application servers, with other automation tools. And, as you change your network, Cloudflare takes care of route management, injecting and withdrawing routes globally across Cloudflare and all connected cloud provider networks.</p><p>Magic Cloud Networking is fully programmable via API, and can be integrated into existing automation toolchains.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3h360ewBWWCRUjhqjrm6wF/5006f8267a880b98ccbe9bfc91cb9029/image7-1.png" />
            
            </figure><p><i>The interface warns when cloud network infrastructure drifts from intent</i></p>
    <div>
      <h2>Ready to start conquering cloud networking?</h2>
      <a href="#ready-to-start-conquering-cloud-networking">
        
      </a>
    </div>
    <p>We are thrilled to introduce Magic Cloud Networking as another pivotal step to fulfilling the promise of the <a href="https://www.cloudflare.com/connectivity-cloud/">Connectivity Cloud</a>. This marks our initial stride in empowering customers to seamlessly integrate Cloudflare with their public clouds to get securely connected, stay securely connected, and gain flexibility and cost savings as they go.</p><p>Join us on this journey for early access: learn more and sign up <a href="https://cloudflare.com/lp/cloud-networking/">here</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/610Vl5u7JVsnszRAmQz0Yt/3bb2a75f47826c1c1969c1d9b0c1db8d/image4-10.png" />
            
            </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[AWS]]></category>
            <category><![CDATA[EC2]]></category>
            <category><![CDATA[Google Cloud]]></category>
            <category><![CDATA[Microsoft Azure]]></category>
            <category><![CDATA[SASE]]></category>
            <category><![CDATA[Cloudflare One]]></category>
            <category><![CDATA[Multi-Cloud]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Magic WAN]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <category><![CDATA[Acquisitions]]></category>
            <guid isPermaLink="false">2qMDjBOoY9rSrSaeNzUDzL</guid>
            <dc:creator>Steve Welham</dc:creator>
            <dc:creator>David Naylor</dc:creator>
        </item>
        <item>
            <title><![CDATA[connect() - why are you so slow?]]></title>
            <link>https://blog.cloudflare.com/linux-transport-protocol-port-selection-performance/</link>
            <pubDate>Thu, 08 Feb 2024 14:00:27 GMT</pubDate>
            <description><![CDATA[ This is our story of what we learned about the connect() implementation for TCP in Linux. Both its strong and weak points. How connect() latency changes under pressure, and how to open connection so that the syscall latency is deterministic and time-bound ]]></description>
            <content:encoded><![CDATA[ <p></p><p>It is no secret that Cloudflare is encouraging companies to deprecate their use of IPv4 addresses and move to IPv6 addresses. We have a couple articles on the subject from this year:</p><ul><li><p><a href="/amazon-2bn-ipv4-tax-how-avoid-paying/">Amazon’s $2bn IPv4 tax – and how you can avoid paying it</a></p></li><li><p><a href="/ipv6-from-dns-pov/">Using DNS to estimate worldwide state of IPv6 adoption</a></p></li></ul><p>And many more in our <a href="/searchresults#q=IPv6&amp;sort=date%20descending&amp;f:@customer_facing_source=[Blog]&amp;f:@language=[English]">catalog</a>. To help with this, we spent time this last year investigating and implementing infrastructure to reduce our internal and egress use of IPv4 addresses. We prefer to re-allocate our addresses than to purchase more due to increasing costs. And in this effort we discovered that our cache service is one of our bigger consumers of IPv4 addresses. Before we remove IPv4 addresses for our cache services, we first need to understand how cache works at Cloudflare.</p>
    <div>
      <h2>How does cache work at Cloudflare?</h2>
      <a href="#how-does-cache-work-at-cloudflare">
        
      </a>
    </div>
    <p>Describing the full scope of the <a href="https://developers.cloudflare.com/reference-architecture/cdn-reference-architecture/#cloudflare-cdn-architecture-and-design">architecture</a> is out of scope of this article, however, we can provide a basic outline:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/70ULgxsqU4zuyWYVrNn6et/8c80079d6dd93083059a875bbf48059d/image1-2.png" />
            
            </figure><ol><li><p>Internet User makes a request to pull an asset</p></li><li><p>Cloudflare infrastructure routes that request to a handler</p></li><li><p>Handler machine returns cached asset, or if miss</p></li><li><p>Handler machine reaches to origin server (owned by a customer) to pull the requested asset</p></li></ol><p>The particularly interesting part is the cache miss case. When a website suddenly becomes very popular, many uncached assets may need to be fetched all at once. Hence we may make an upwards of: 50k TCP unicast connections to a single destination_._</p><p>That is a lot of connections! We have strategies in place to limit the impact of this or avoid this problem altogether. But in these rare cases when it occurs, we will then balance these connections over two source IPv4 addresses.</p><p>Our goal is to remove the load balancing and prefer one IPv4 address. To do that, we need to understand the performance impact of two IPv4 addresses vs one.</p>
    <div>
      <h2>TCP connect() performance of two source IPv4 addresses vs one IPv4 address</h2>
      <a href="#tcp-connect-performance-of-two-source-ipv4-addresses-vs-one-ipv4-address">
        
      </a>
    </div>
    <p>We leveraged a tool called <a href="https://github.com/wg/wrk">wrk</a>, and modified it to distribute connections over multiple source IP addresses. Then we ran a workload of 70k connections over 48 threads for a period of time.</p><p>During the test we measured the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/tcp_ipv4.c#L201">tcp_v4_connect()</a> with the BPF BCC libbpf-tool <a href="https://github.com/iovisor/bcc/blob/master/libbpf-tools/funclatency.c">funclatency</a> tool to gather latency metrics as time progresses.</p><p>Note that throughout the rest of this article, all the numbers are specific to a single machine with no production traffic. We are making the assumption that if we can improve a worse case scenario in an algorithm with a best case machine, that the results could be extrapolated to production. Lock contention was specifically taken out of the equation, but will have production implications.</p>
    <div>
      <h3>Two IPv4 addresses</h3>
      <a href="#two-ipv4-addresses">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1q7v3WNgI5X3JQg5ua0B8g/5b557ca762a08422badae379233dee76/image6.png" />
            
            </figure><p>The y-axis are buckets of nanoseconds in powers of ten. The x-axis represents the number of connections made per bucket. Therefore, more connections in a lower power of ten buckets is better.</p><p>We can see that the majority of the connections occur in the fast case with roughly ~20k in the slow case. We should expect this bimodal to increase over time due to wrk continuously closing and establishing connections.</p><p>Now let us look at the performance of one IPv4 address under the same conditions.</p>
    <div>
      <h3>One IPv4 address</h3>
      <a href="#one-ipv4-address">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6kpueuXS3SbBTIig306IDN/b27ab899656fbfc0bf3c885a44fb04a4/image8.png" />
            
            </figure><p>In this case, the bimodal distribution is even more pronounced. Over half of the total connections are in the slow case than in the fast! We may conclude that simply switching to one IPv4 address for cache egress is going to introduce significant latency on our connect() syscalls.</p><p>The next logical step is to figure out where this bottleneck is happening.</p>
    <div>
      <h2>Port selection is not what you think it is</h2>
      <a href="#port-selection-is-not-what-you-think-it-is">
        
      </a>
    </div>
    <p>To investigate this, we first took a flame graph of a production machine:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1tFwadYDdC5UVK78j4yKsv/64aca09189acba5bf3dab2e043265e0f/image7.png" />
            
            </figure><p>Flame graphs depict a run-time function call stack of a system. Y-axis depicts call-stack depth, and x-axis depicts a function name in a horizontal bar that represents the amount of times the function was sampled. Checkout this in-depth <a href="https://www.brendangregg.com/flamegraphs.html">guide</a> about flame graphs for more details.</p><p>Most of the samples are taken in the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1000"><code>__inet_hash_connect()</code></a>. We can see that there are also many samples for <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L544"><code>__inet_check_established()</code></a> with some lock contention sampled between. We have a better picture of a potential bottleneck, but we do not have a consistent test to compare against.</p><p>Wrk introduces a bit more variability than we would like to see. Still focusing on the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/tcp_ipv4.c#L201"><code>tcp_v4_connect()</code></a>, we performed another synthetic test with a homegrown benchmark tool to test one IPv4 address. A tool such as <a href="https://github.com/ColinIanKing/stress-ng">stress-ng</a> may also be used, but some modification is necessary to implement the socket option <a href="https://man7.org/linux/man-pages/man7/ip.7.html"><code>IP_LOCAL_PORT_RANGE</code></a>. There is more about that socket option later.</p><p>We are now going to ensure a deterministic amount of connections, and remove lock contention from the problem. The result is something like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5d6tJum5BBe3jsLRqhXtFN/7952fb3d0a3da761de158fae4f925eb5/Screenshot-2024-02-07-at-15.54.29.png" />
            
            </figure><p>On the y-axis we measured the latency between the start and end of a connect() syscall. The x-axis denotes when a connect() was called. Green dots are even numbered ports, and red dots are odd numbered ports. The orange line is a linear-regression on the data.</p><p>The disparity between the average time for port allocation between even and odd ports provides us with a major clue. Connections with odd ports are found significantly slower than the even. Further, odd ports are not interleaved with earlier connections. This implies we exhaust our even ports before attempting the odd. The chart also confirms our bimodal distribution.</p>
    <div>
      <h3>__inet_hash_connect()</h3>
      <a href="#__inet_hash_connect">
        
      </a>
    </div>
    <p>At this point we wanted to understand this split a bit better. We know from the flame graph and the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1000"><code>__inet_hash_connect()</code></a> that this holds the algorithm for port selection. For context, this function is responsible for associating the socket to a source port in a late bind. If a port was previously provided with bind(), the algorithm just tests for a unique TCP 4-tuple (src ip, src port, dest ip, dest port) and ignores port selection.</p><p>Before we dive in, there is a little bit of setup work that happens first. Linux first generates a time-based hash that is used as the basis for the starting port, then adds randomization, and then puts that information into an offset variable. This is always set to an even integer.</p><p><a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1043">net/ipv4/inet_hashtables.c</a></p>
            <pre><code>   offset &amp;= ~1U;
    
other_parity_scan:
    port = low + offset;
    for (i = 0; i &lt; remaining; i += 2, port += 2) {
        if (unlikely(port &gt;= high))
            port -= remaining;

        inet_bind_bucket_for_each(tb, &amp;head-&gt;chain) {
            if (inet_bind_bucket_match(tb, net, port, l3mdev)) {
                if (!check_established(death_row, sk, port, &amp;tw))
                    goto ok;
                goto next_port;
            }
        }
    }

    offset++;
    if ((offset &amp; 1) &amp;&amp; remaining &gt; 1)
        goto other_parity_scan;</code></pre>
            <p>Then in a nutshell: loop through one half of ports in our range (all even or all odd ports) before looping through the other half of ports (all odd or all even ports respectively) for each connection. Specifically, this is a variation of the <a href="https://datatracker.ietf.org/doc/html/rfc6056#section-3.3.4">Double-Hash Port Selection Algorithm</a>. We will ignore the bind bucket functionality since that is not our main concern.</p><p>Depending on your port range, you either start with an even port or an odd port. In our case, our low port, 9024, is even. Then the port is picked by adding the offset to the low port:</p><p><a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1045">net/ipv4/inet_hashtables.c</a></p>
            <pre><code>port = low + offset;</code></pre>
            <p>If low was odd, we will have an odd starting port because odd + even = odd.</p><p>There is a bit too much going on in the loop to explain in text. I have an example instead:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6uVqtAUR07epRRKqQbHWkp/2a5671b1dd3c68c012e7171b8103a53e/image5.png" />
            
            </figure><p>This example is bound by 8 ports and 8 possible connections. All ports start unused. As a port is used up, the port is grayed out. Green boxes represent the next chosen port. All other colors represent open ports. Blue arrows are even port iterations of offset, and red are the odd port iterations of offset. Note that the offset is randomly picked, and once we cross over to the odd range, the offset is incremented by one.</p><p>For each selection of a port, the algorithm then makes a call to the function <code>check_established()</code> which dereferences <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L544"><code>__inet_check_established()</code></a>. This function loops over sockets to verify that the TCP 4-tuple is unique. The takeaway is that the socket list in the function is usually smaller than not. This grows as more unique TCP 4-tuples are introduced to the system. Longer socket lists may slow down port selection eventually. We have a blog post on <a href="/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/">ephemeral port exhausting</a> that dives into the socket list and port uniqueness criteria.</p><p>At this point, we can summarize that the odd/even port split is what is causing our performance bottleneck. And during the investigation, it was not obvious to me (or even maybe you) why the offset was initially calculated the way it was, and why the odd/even port split was introduced. After some git-archaeology the decisions become more clear.</p>
    <div>
      <h3>Security considerations</h3>
      <a href="#security-considerations">
        
      </a>
    </div>
    <p>Port selection has been shown to be used in device <a href="https://lwn.net/Articles/910435/">fingerprinting</a> in the past. This led the authors to introduce more randomization into the initial port selection. Prior, ports were predictably picked solely based on their initial hash and a salt value which does not change often. This helps with explaining the offset, but does not explain the split.</p>
    <div>
      <h3>Why the even/odd split?</h3>
      <a href="#why-the-even-odd-split">
        
      </a>
    </div>
    <p>Prior to this <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=07f4c90062f8fc7c8c26f8f95324cbe8fa3145a5">patch</a> and that <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1580ab63fc9a03593072cc5656167a75c4f1d173">patch</a>, services may have conflicts between the connect() and bind() heavy workloads. Thus, to avoid those conflicts, the split was added. An even offset was chosen for the connect() workloads, and an odd offset for the bind() workloads. However, we can see that the split works great for connect() workloads that do not exceed one half of the allotted port range.</p><p>Now we have an explanation for the flame graph and charts. So what can we do about this?</p>
    <div>
      <h2>User space solution (kernel &lt; 6.8)</h2>
      <a href="#user-space-solution-kernel-6-8">
        
      </a>
    </div>
    <p>We have a couple of strategies that would work best for us. Infrastructure or architectural strategies are not considered due to significant development effort. Instead, we prefer to tackle the problem where it occurs.</p><h3>Select, test, repeat<p>For the “select, test, repeat” approach, you may have code that ends up looking like this:</p>
            <pre><code>sys = get_ip_local_port_range()
estab = 0
i = sys.hi
while i &gt;= 0:
    if estab &gt;= sys.hi:
        break

    random_port = random.randint(sys.lo, sys.hi)
    connection = attempt_connect(random_port)
    if connection is None:
        i += 1
        continue

    i -= 1
    estab += 1</code></pre>
            <p>The algorithm simply loops through the system port range, and randomly picks a port each iteration. Then test that the connect() worked. If not, rinse and repeat until range exhaustion.</p><p>This approach is good for up to ~70-80% port range utilization. And this may take roughly eight to twelve attempts per connection as we approach exhaustion. The major downside to this approach is the extra syscall overhead on conflict. In order to reduce this overhead, we can consider another approach that allows the kernel to still select the port for us.</p><h3>Select port by random shifting range<p>This approach leverages the <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91d0b78c5177f3e42a4d8738af8ac19c3a90d002"><code>IP_LOCAL_PORT_RANGE</code></a> socket option. And we were able to achieve performance like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Uz8whp12VuvqvKTDnE1u9/4701177d739bdffe2a2399213cf72941/Screenshot-2024-02-07-at-16.00.22.png" />
            
            </figure><p>That is much better! The chart also introduces black dots that represent errored connections. However, they have a tendency to clump at the very end of our port range as we approach exhaustion. This is not dissimilar to what we may see in “<a href="#selecttestrepeat">select, test, repeat</a>”.</p><p>The way this solution works is something like:</p>
            <pre><code>IP_BIND_ADDRESS_NO_PORT = 24
IP_LOCAL_PORT_RANGE = 51
sys = get_local_port_range()
window.lo = 0
window.hi = 1000
range = window.hi - window.lo
offset = randint(sys.lo, sys.hi - range)
window.lo = offset
window.hi = offset + range

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1)
range = pack("@I", window.lo | (window.hi &lt;&lt; 16))
sk.setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE, range)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>We first fetch the system's local port range, define a custom port range, and then randomly shift the custom range within the system range. Introducing this randomization helps the kernel to start port selection randomly at an odd or even port. Then reduces the loop search space down to the range of the custom window.</p><p>We tested with a few different window sizes, and determined that a five hundred or one thousand size works fairly well for our port range:</p>
<table>
<thead>
  <tr>
    <th><span>Window size</span></th>
    <th><span>Errors</span></th>
    <th><span>Total test time</span></th>
    <th><span>Connections/second</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>500</span></td>
    <td><span>868</span></td>
    <td><span>~1.8 seconds</span></td>
    <td><span>~30,139</span></td>
  </tr>
  <tr>
    <td><span>1,000</span></td>
    <td><span>1,129</span></td>
    <td><span>~2 seconds</span></td>
    <td><span>~27,260</span></td>
  </tr>
  <tr>
    <td><span>5,000</span></td>
    <td><span>4,037</span></td>
    <td><span>~6.7 seconds</span></td>
    <td><span>~8,405</span></td>
  </tr>
  <tr>
    <td><span>10,000</span></td>
    <td><span>6,695</span></td>
    <td><span>~17.7 seconds</span></td>
    <td><span>~3,183</span></td>
  </tr>
</tbody>
</table><p>As the window size increases, the error rate increases. That is because a larger window provides less random offset opportunity. A max window size of 56,512 is no different from using the kernels default behavior. Therefore, a smaller window size works better. But you do not want it to be too small either. A window size of one is no different from “<a href="#selecttestrepeat">select, test, repeat</a>”.</p><p>In kernels &gt;= 6.8, we can do even better.</p><h2>Kernel solution (kernel &gt;= 6.8)</h2><p>A new <a href="https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=207184853dbd">patch</a> was introduced that eliminates the need for the window shifting. This solution is going to be available in the 6.8 kernel.</p><p>Instead of picking a random window offset for <code>setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE</code>, …), like in the previous solution, we instead just pass the full system port range to activate the solution. The code may look something like this:</p>
            <pre><code>IP_BIND_ADDRESS_NO_PORT = 24
IP_LOCAL_PORT_RANGE = 51
sys = get_local_port_range()
sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1)
range = pack("@I", sys.lo | (sys.hi &lt;&lt; 16))
sk.setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE, range)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>Setting <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91d0b78c5177f3e42a4d8738af8ac19c3a90d002"><code>IP_LOCAL_PORT_RANGE</code></a> option is what tells the kernel to use a similar approach to “<a href="#random">select port by random shifting range</a>” such that the start offset is randomized to be even or odd, but then loops incrementally rather than skipping every other port. We end up with results like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ttWStZgNYfwftr71r8Vrt/7c333411ef01b674cc839f27ae4cbbbf/Screenshot-2024-02-07-at-16.04.24.png" />
            
            </figure><p>The performance of this approach is quite comparable to our user space implementation. Albeit, a little faster. Due in part to general improvements, and that the algorithm can always find a port given the full search space of the range. Then there are no cycles wasted on a potentially filled sub-range.</p><p>These results are great for TCP, but what about other protocols?</p>
    <div>
      <h2>Other protocols &amp; connect()</h2>
      <a href="#other-protocols-connect">
        
      </a>
    </div>
    <p>It is worth mentioning at this point that the algorithms used for the protocols are <i>mostly</i> the same for IPv4 &amp; IPv6. Typically, the key difference is how the sockets are compared to determine uniqueness and where the port search happens. We did not compare performance for all protocols. But it is worth mentioning some similarities and differences with TCP and a couple of others.</p>
    <div>
      <h3>DCCP</h3>
      <a href="#dccp">
        
      </a>
    </div>
    <p>The DCCP protocol leverages the same port selection <a href="https://elixir.bootlin.com/linux/v6.6/source/net/dccp/ipv4.c#L115">algorithm</a> as TCP. Therefore, this protocol benefits from the recent kernel changes. It is also possible the protocol could benefit from our user space solution, but that is untested. We will let the reader exercise DCCP use-cases.</p>
    <div>
      <h3>UDP &amp; UDP-Lite</h3>
      <a href="#udp-udp-lite">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/ddos/glossary/user-datagram-protocol-udp/">UDP</a> leverages a different algorithm found in the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/udp.c#L239"><code>udp_lib_get_port()</code></a>. Similar to TCP, the algorithm will loop over the whole port range space incrementally. This is only the case if the port is not already supplied in the bind() call. The key difference between UDP and TCP is that a random number is generated as a step variable. Then, once a first port is identified, the algorithm loops on that port with the random number. This relies on an uint16_t overflow to eventually loop back to the chosen port. If all ports are used, increment the port by one and repeat. There is no port splitting between even and odd ports.</p><p>The best comparison to the TCP measurements is a UDP setup similar to:</p>
            <pre><code>sk = socket(AF_INET, SOCK_DGRAM)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>And the results should be unsurprising with one IPv4 source address:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4UM5d0RBTgqADgVLbbqMlQ/940306c90767ba4b5e3762c6467b71ed/Screenshot-2024-02-07-at-16.06.27.png" />
            
            </figure><p>UDP fundamentally behaves differently from TCP. And there is less work overall for port lookups. The outliers in the chart represent a worst-case scenario when we reach a fairly bad random number collision. In that case, we need to more-completely loop over the ephemeral range to find a port.</p><p>UDP has another problem. Given the socket option <code>SO_REUSEADDR</code>, the port you get back may conflict with another UDP socket. This is in part due to the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/udp.c#L141"><code>udp_lib_lport_inuse()</code></a> ignoring the UDP 2-tuple (src ip, src port) check given the socket option. When this happens you may have a new socket that overwrites a previous. Extra care is needed in that case. We wrote more in depth about these cases in a previous <a href="/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/">blog post</a>.</p>
    <div>
      <h2>In summary</h2>
      <a href="#in-summary">
        
      </a>
    </div>
    <p>Cloudflare can make a lot of unicast egress connections to origin servers with popular uncached assets. To avoid port-resource exhaustion, we balance the load over a couple of IPv4 source addresses during those peak times. Then we asked: “what is the performance impact of one IPv4 source address for our connect()-heavy workloads?”. Port selection is not only difficult to get right, but is also a performance bottleneck. This is evidenced by measuring connect() latency with a flame graph and synthetic workloads. That then led us to discovering TCP’s quirky port selection process that loops over half your ephemeral ports before the other for each connect().</p><p>We then proposed three solutions to solve the problem outside of adding more IP addresses or other architectural changes: “<a href="#selecttestrepeat">select, test, repeat</a>”, “<a href="#random">select port by random shifting range</a>”, and an <a href="https://man7.org/linux/man-pages/man7/ip.7.html"><code>IP_LOCAL_PORT_RANGE</code></a> socket option <a href="#kernel">solution</a> in newer kernels. And finally closed out with other protocol honorable mentions and their quirks.</p><p>Do not take our numbers! Please explore and measure your own systems. With a better understanding of your workloads, you can make a good decision on which strategy works best for your needs. Even better if you come up with your own strategy!</p></h3></h3> ]]></content:encoded>
            <category><![CDATA[Linux]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[IPv4]]></category>
            <category><![CDATA[IPv6]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">1C6z0btasEsz1cmdmoug0m</guid>
            <dc:creator>Frederick Lawler</dc:creator>
        </item>
        <item>
            <title><![CDATA[How Cloudflare’s systems dynamically route traffic across the globe]]></title>
            <link>https://blog.cloudflare.com/meet-traffic-manager/</link>
            <pubDate>Mon, 25 Sep 2023 13:00:16 GMT</pubDate>
            <description><![CDATA[ Meet the smartest member of the Cloudflare network team that helps keep you online no matter what happens to the Internet underneath us ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4NgKY8lcObRRPp4XUwHWRH/fd6462ace767589fd26f2f52aa98252f/image14-1.png" />
            
            </figure><p>Picture this: you’re at an airport, and you’re going through an airport security checkpoint. There are a bunch of agents who are scanning your boarding pass and your passport and sending you through to your gate. All of a sudden, some of the agents go on break. Maybe there’s a leak in the ceiling above the checkpoint. Or perhaps a bunch of flights are leaving at 6pm, and a number of passengers turn up at once. Either way, this imbalance between localized supply and demand can cause huge lines and unhappy travelers — who just want to get through the line to get on their flight. How do airports handle this?</p><p>Some airports may not do anything and just let you suffer in a longer line. Some airports may offer fast-lanes through the checkpoints for a fee. But most airports will tell you to go to another security checkpoint a little farther away to ensure that you can get through to your gate as fast as possible. They may even have signs up telling you how long each line is, so you can make an easier decision when trying to get through.</p><p>At Cloudflare, we have the same problem. We are located in 300 cities around the world that are built to receive end-user traffic for all of our product suites. And in an ideal world, we always have enough computers and bandwidth to handle everyone at their closest possible location. But the world is not always ideal; sometimes we take a data center offline for maintenance, or a connection to a data center goes down, or some equipment fails, and so on. When that happens, we may not have enough attendants to serve every person going through security in every location. It’s not because we haven’t built enough kiosks, but something has happened in our data center that prevents us from serving everyone.</p><p>So, we built Traffic Manager: a tool that balances supply and demand across our entire global network. This blog is about Traffic Manager: how it came to be, how we built it, and what it does now.</p>
    <div>
      <h3>The world before Traffic Manager</h3>
      <a href="#the-world-before-traffic-manager">
        
      </a>
    </div>
    <p>The job now done by Traffic Manager used to be a manual process carried out by network engineers: our network would operate as normal until something happened that caused user traffic to be impacted at a particular data center.</p><p>When such events happened, user requests would start to fail with 499 or 500 errors because there weren’t enough machines to handle the request load of our users. This would trigger a page to our network engineers, who would then remove some Anycast routes for that data center. The end result: by no longer advertising those prefixes in the impacted data center, user traffic would divert to a different data center. This is how Anycast fundamentally works: user traffic is drawn to the closest data center advertising the prefix the user is trying to connect to, as determined by Border Gateway Protocol. For a primer on what Anycast is, check out <a href="https://www.cloudflare.com/learning/cdn/glossary/anycast-network/">this reference article</a>.</p><p>Depending on how bad the problem was, engineers would remove some or even all the routes in a data center. When the data center was again able to absorb all the traffic, the engineers would put the routes back and the traffic would return naturally to the data center.</p><p>As you might guess, this was a challenging task for our network engineers to do every single time any piece of hardware on our network had an issue. It didn’t scale.</p>
    <div>
      <h3>Never send a human to do a machine’s job</h3>
      <a href="#never-send-a-human-to-do-a-machines-job">
        
      </a>
    </div>
    <p>But doing it manually wasn’t just a burden on our Network Operations team. It also resulted in a sub-par experience for our customers; our engineers would need to take time to diagnose and re-route traffic. To solve both these problems, we wanted to build a service that would immediately and automatically detect if users were unable to reach a Cloudflare data center, and withdraw routes from the data center until users were no longer seeing issues. Once the service received notifications that the impacted data center could absorb the traffic, it could put the routes back and reconnect that data center. This service is called Traffic Manager, because its job (as you might guess) is to manage traffic coming into the Cloudflare network.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/38NInVKI4VizcCukXlF7o4/77758610378a6721ecf30127b6246d0f/image19.png" />
            
            </figure>
    <div>
      <h3>Accounting for second order consequences</h3>
      <a href="#accounting-for-second-order-consequences">
        
      </a>
    </div>
    <p>When a network engineer removes a route from a router, they can make the best guess at where the user requests will move to, and try to ensure that the failover data center has enough resources to handle the requests — if it doesn’t, they can adjust the routes there accordingly prior to removing the route in the initial data center. To be able to automate this process, we needed to move from a world of intuition to a world of data — accurately predicting where traffic would go when a route was removed, and feeding this information to Traffic Manager, so it could ensure it doesn’t make the situation worse.</p>
    <div>
      <h3>Meet Traffic Predictor</h3>
      <a href="#meet-traffic-predictor">
        
      </a>
    </div>
    <p>Although we can adjust which data centers advertise a route, we are unable to influence what proportion of traffic each data center receives. Each time we add a new data center, or a new peering session, the distribution of traffic changes, and as we are in over 300 cities and 12,500 peering sessions, it has become quite difficult for a human to keep track of, or predict the way traffic will move around our network. Traffic manager needed a buddy: Traffic Predictor.</p><p>In order to do its job, Traffic Predictor carries out an ongoing series of real world tests to see where traffic actually moves. Traffic Predictor relies on a testing system that simulates removing a data center from service and measuring where traffic would go if that data center wasn’t serving traffic. To help understand how this system works, let’s simulate the removal of a subset of a data center in Christchurch, New Zealand:</p><ul><li><p>First, Traffic Predictor gets a list of all the IP addresses that normally connect to Christchurch. Traffic Predictor will send a ping request to hundreds of thousands of IPs that have recently made a request there.</p></li><li><p>Traffic Predictor records if the IP responds, and whether the response returns to Christchurch using a special Anycast IP range specifically configured for Traffic Predictor.</p></li><li><p>Once Traffic Predictor has a list of IPs that respond to Christchurch, it removes that route containing that special range from Christchurch, waits a few minutes for the Internet routing table to be updated, and runs the test again.</p></li><li><p>Instead of being routed to Christchurch, the responses are instead going to data centers around Christchurch. Traffic Predictor then uses the knowledge of responses for each data center, and records the results as the failover for Christchurch.</p></li></ul><p>This allows us to simulate Christchurch going offline without actually taking Christchurch offline!</p><p>But Traffic Predictor doesn’t just do this for any one data center. To add additional layers of resiliency, Traffic Predictor even calculates a second layer of indirection: for each data center failure scenario, Traffic Predictor also calculates failure scenarios and creates policies for when surrounding data centers fail.</p><p>Using our example from before, when Traffic Predictor tests Christchurch, it will run a series of tests that remove several surrounding data centers from service including Christchurch to calculate different failure scenarios. This ensures that even if something catastrophic happens which impacts multiple data centers in a region, we still have the ability to serve user traffic. If you think this data model is complicated, you’re right: it takes several days to calculate all of these failure paths and policies.</p><p>Here’s what those failure paths and failover scenarios look like for all of our data centers around the world when they’re visualized:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4NxD3OynAnVJFP9yfv9pa1/1b518728e831062aa5bcae1d8329ffe8/image17.png" />
            
            </figure><p>This can be a bit complicated for humans to parse, so let’s dig into that above scenario for Christchurch, New Zealand to make this a bit more clear. When we take a look at failover paths specifically for Christchurch, we see they look like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6JGMDbR9jjZHFTpQMEkfZI/29dbc0bfeb4fa4147156d331831d8ebc/image20.png" />
            
            </figure><p>In this scenario we predict that 99.8% of Christchurch’s traffic would shift to Auckland, which is able to absorb all Christchurch traffic in the event of a catastrophic outage.</p><p>Traffic Predictor allows us to not only see where traffic will move to if something should happen, but it allows us to preconfigure Traffic Manager policies to move requests out of failover data centers to prevent a thundering herd scenario: where sudden influx of requests can cause failures in a second data center if the first one has issues. With Traffic Predictor, Traffic Manager doesn’t just move traffic out of one data center when that one fails, but it also proactively moves traffic out of other data centers to ensure a seamless continuation of service.</p>
    <div>
      <h3>From a sledgehammer to a scalpel</h3>
      <a href="#from-a-sledgehammer-to-a-scalpel">
        
      </a>
    </div>
    <p>With Traffic Predictor, Traffic Manager can dynamically advertise and withdraw prefixes while ensuring that every datacenter can handle all the traffic. But withdrawing prefixes as a means of traffic management can be a bit heavy-handed at times. One of the reasons for this is that the only way we had to add or remove traffic to a data center was through advertising routes from our Internet-facing routers. Each one of our routes has thousands of IP addresses, so removing only one still represents a large portion of traffic.</p><p>Specifically, Internet applications will advertise prefixes to the Internet from a /24 subnet at an absolute minimum, but many will advertise prefixes larger than that. This is generally done to prevent things like route leaks or route hijacks: many providers will actually filter out routes that are more specific than a /24 (for more information on that, check out this blog on <a href="/route-leak-detection-with-cloudflare-radar/">how we detect route leaks</a>). If we assume that Cloudflare maps protected properties to IP addresses at a 1:1 ratio, then each /24 subnet would be able to service 256 customers, which is the number of IP addresses in a /24 subnet. If every IP address sent one request per second, we’d have to move 4 /24 subnets out of a data center if we needed to move 1,000 requests per second (RPS).</p><p>But in reality, Cloudflare maps a single IP address to hundreds of thousands of protected properties. So for Cloudflare, a /24 might take 3,000 requests per second, but if we needed to move 1,000 RPS out, we would have no choice but to move a single /24 out. And that’s just assuming we advertise at a /24 level. If we used /20s to advertise, the amount we can withdraw gets less granular: at a 1:1 website to IP address mapping, that’s 4,096 requests per second for each prefix, and even more if the website to IP address mapping is many to one.</p><p>While withdrawing prefix advertisements improved the customer experience for those users who would have seen a 499 or 500 error — there may have been a significant portion of users who wouldn’t have been impacted by an issue who still were moved away from the data center they should have gone to, probably slowing them down, even if only a little bit. This concept of moving more traffic out than is necessary is called “stranding capacity”: the data center is theoretically able to service more users in a region but cannot because of how Traffic Manager was built.</p><p>We wanted to improve Traffic Manager so that it only moved the absolute minimum of users out of a data center that was seeing a problem and not strand any more capacity. To do so, we needed to shift percentages of prefixes, so we could be extra fine-grained and only move the things that absolutely need to be moved. To solve this, we built an extension of our <a href="/unimog-cloudflares-edge-load-balancer/">Layer 4 load balancer Unimog,</a> which we call Plurimog.</p><p>A quick refresher on Unimog and layer 4 load balancing: every single one of our machines contains a service that determines whether that machine can take a user request. If the machine can take a user request then it sends the request to our HTTP stack which processes the request before returning it to the user. If the machine can’t take the request, the machine sends the request to another machine in the data center that can. The machines can do this because they are constantly talking to each other to understand whether they can serve requests for users.</p><p>Plurimog does the same thing, but instead of talking between machines, Plurimog talks in between data centers and points of presence. If a request goes into Philadelphia and Philadelphia is unable to take the request, Plurimog will forward to another data center that can take the request, like Ashburn, where the request is decrypted and processed. Because Plurimog operates at layer 4, it can send individual TCP or UDP requests to other places which allows it to be very fine-grained: it can send percentages of traffic to other data centers very easily, meaning that we only need to send away enough traffic to ensure that everyone can be served as fast as possible. Check out how that works in our Frankfurt data center, as we are able to shift progressively more and more traffic away to handle issues in our data centers. This chart shows the number of actions taken on free traffic that cause it to be sent out of Frankfurt over time:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2NqLJgn8hYCuHKXRaJfX2P/c666ab9c6c8aba3071a3528b274f997b/pasted-image-0-1.png" />
            
            </figure><p>But even within a data center, we can route traffic around to prevent traffic from leaving the datacenter at all. Our large data centers, called Multi-Colo Points of Presence (MCPs) contain logical sections of compute within a data center that are distinct from one another. These MCP data centers are enabled with another version of Unimog called Duomog, which allows for traffic to be shifted between logical sections of compute automatically. This makes MCP data centers fault-tolerant without sacrificing performance for our customers, and allows Traffic Manager to work within a data center as well as between data centers.</p><p>When evaluating portions of requests to move, Traffic Manager does the following:</p><ul><li><p>Traffic Manager identifies the proportion of requests that need to be removed from a data center or subsection of a data center so that all requests can be served.</p></li><li><p>Traffic Manager then calculates the aggregated space metrics for each target to see how many requests each failover data center can take.</p></li><li><p>Traffic Manager then identifies how much traffic in each plan we need to move, and moves either a proportion of the plan, or all of the plan through Plurimog/Duomog, until we've moved enough traffic. We move Free customers first, and if there are no more Free customers in a data center, we'll move Pro, and then Business customers if needed.</p></li></ul><p>For example, let’s look at Ashburn, Virginia: one of our MCPs. Ashburn has nine different subsections of capacity that can each take traffic. On 8/28, one of those subsections, IAD02, had an issue that reduced the amount of traffic it could handle.</p><p>During this time period, Duomog sent more traffic from IAD02 to other subsections within Ashburn, ensuring that Ashburn was always online, and that performance was not impacted during this issue. Then, once IAD02 was able to take traffic again, Duomog shifted traffic back automatically. You can see these actions visualized in the time series graph below, which tracks the percentage of traffic moved over time between subsections of capacity within IAD02 (shown in green):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2tHxLx4GG2vfqVOfscJlCr/c4864e24dc18b7ad1866c716862d79ee/pasted-image-0--1--1.png" />
            
            </figure>
    <div>
      <h3>How does Traffic Manager know how much to move?</h3>
      <a href="#how-does-traffic-manager-know-how-much-to-move">
        
      </a>
    </div>
    <p>Although we used requests per second in the example above, using requests per second as a metric isn’t accurate enough when actually moving traffic. The reason for this is that different customers have different resource costs to our service; a website served mainly from cache with the WAF deactivated is much cheaper CPU wise than a site with all WAF rules enabled and caching disabled. So we record the time that each request takes in the CPU. We can then aggregate the CPU time across each plan to find the CPU time usage per plan. We record the CPU time in ms, and take a per second value, resulting in a unit of milliseconds per second.</p><p>CPU time is an important metric because of the impact it can have on latency and customer performance. As an example, consider the time it takes for an eyeball request to make it entirely through the Cloudflare front line servers: we call this the cfcheck latency. If this number goes too high, then our customers will start to notice, and they will have a bad experience. When cfcheck latency gets high, it’s usually because CPU utilization is high. The graph below shows 95th percentile cfcheck latency plotted against CPU utilization across all the machines in the same data center, and you can see the strong correlation:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ZNFbWlf35KUMAh9SchRHb/4e415f7d847d10bbe68585c9a7695266/Untitled.png" />
            
            </figure><p>So having Traffic Manager look at CPU time in a data center is a very good way to ensure that we’re giving customers the best experience and not causing problems.</p><p>After getting the CPU time per plan, we need to figure out how much of that CPU time to move to other data centers. To do this, we aggregate the CPU utilization across all servers to give a single CPU utilization across the data center. If a proportion of servers in the data center fail, due to network device failure, power failure, etc., then the requests that were hitting those servers are automatically routed elsewhere within the data center by Duomog. As the number of servers decrease, the overall CPU utilization of the data center increases. Traffic Manager has three thresholds for each data center; the maximum threshold, the target threshold, and the acceptable threshold:</p><ul><li><p>Maximum: the CPU level at which performance starts to degrade, where Traffic Manager will take action</p></li><li><p>Target: the level to which Traffic Manager will try to reduce the CPU utilization to restore optimal service to users</p></li><li><p>Acceptable: the level below which a data center can receive requests forwarded from another data center, or revert active moves</p></li></ul><p>When a data center goes above the maximum threshold, Traffic Manager takes the ratio of total CPU time across all plans to current CPU utilization, then applies that to the target CPU utilization to find the target CPU time. Doing it this way means we can compare a data center with 100 servers to a data center with 10 servers, without having to worry about the number of servers in each data center. This assumes that load increases linearly, which is close enough to true for the assumption to be valid for our purposes.</p><p>Target ratio equals current ratio:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2EGE8UPINB9MUPtpETprf5/0f82d6166774a63f8e252dea7f169490/Screenshot-2023-09-18-at-22.11.27.png" />
            
            </figure><p>Therefore:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/uyhAhuKbaFhMpdxtJTBFq/89f9032c5e4380b895f5bf9542ced1d9/Screenshot-2023-09-18-at-22.12.17.png" />
            
            </figure><p>Subtracting the target CPU time from the current CPU time gives us the CPU time to move:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4SQDzRDMKby1OrhYxrLhBY/74142207095c5b9a4e869e2fe735ce6f/Screenshot-2023-09-18-at-22.13.14.png" />
            
            </figure><p>For example, if the current CPU utilization was at 90% across the data center, the target was 85%, and the CPU time across all plans was 18,000, we would have:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2A074OHvmPertIwkAIb0ev/e49abb26ac4b17cba2a96a4e5ccb7a8f/Screenshot-2023-09-18-at-22.14.02.png" />
            
            </figure><p>This would mean Traffic Manager would need to move 1,000 CPU time:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/qKnOiyzymcphDes5ee2cS/d7cec01541398c1b3ae1b075622626c9/Screenshot-2023-09-25-at-10.44.41.png" />
            
            </figure><p>Now we know the total CPU time needed to move, we can go through the plans, until the required time to move has been met.</p>
    <div>
      <h3>What is the maximum threshold?</h3>
      <a href="#what-is-the-maximum-threshold">
        
      </a>
    </div>
    <p>A frequent problem that we faced was determining at which point Traffic Manager should start taking action in a data center - what metric should it watch, and what is an acceptable level?</p><p>As said before, different services have different requirements in terms of CPU utilization, and there are many cases of data centers that have very different utilization patterns.</p><p>To solve this problem, we turned to <a href="https://www.cloudflare.com/learning/ai/what-is-machine-learning/">machine learning</a>. We created a service that will automatically adjust the maximum thresholds for each data center according to customer-facing indicators. For our main service-level indicator (SLI), we decided to use the cfcheck latency metric we described earlier.</p><p>But we also need to define a service-level objective (SLO) in order for our machine learning application to be able to adjust the threshold. We set the SLO for 20ms. Comparing our SLO to our SLI, our 95th percentile cfcheck latency should never go above 20ms and if it does, we need to do something. The below graph shows 95th percentile cfcheck latency over time, and customers start to get unhappy when cfcheck latency goes into the red zone:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3A9IRcG1ztxPxIxF0ljSLj/9db6c767756a2e0e17b7c8b1d00089fa/Untitled--1-.png" />
            
            </figure><p>If customers have a bad experience when CPU gets too high, then the goal of Traffic Manager’s maximum thresholds are to ensure that customer performance isn’t impacted and to start redirecting traffic away before performance starts to degrade. At a scheduled interval the Traffic Manager service will fetch a number of metrics for each data center and apply a series of machine learning algorithms. After cleaning the data for outliers we apply a simple quadratic curve fit, and we are currently testing a linear regression algorithm.</p><p>After fitting the models we can use them to predict the CPU usage when the SLI is equal to our SLO, and then use it as our maximum threshold. If we plot the cpu values against the SLI we can see clearly why these methods work so well for our data centers, as you can see for Barcelona in the graphs below, which are plotted against curve fit and linear regression fit respectively.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/695BSI9vd6OJ0jfhHwSj43/df037d425ddf50b3579696c770e6ff80/Untitled--2-.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2LDLfdY2PNOTJjA1FU6lQM/e4341455c659795ce9ee2e004d1eb5b0/Untitled--3-.png" />
            
            </figure><p>In these charts the vertical line is the SLO, and the intersection of this line with the fitted model represents the value that will be used as the maximum threshold. This model has proved to be very accurate, and we are able to significantly reduce the SLO breaches. Let’s take a look at when we started deploying this service in Lisbon:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/vK8dNvcvRFb0L9WiKuaOI/9ed8d056f903d5ce09b62515c6ecb9c2/Untitled--4-.png" />
            
            </figure><p>Before the change, cfcheck latency was constantly spiking, but Traffic Manager wasn’t taking actions because the maximum threshold was static. But after July 29, we see that cfcheck latency has never hit the SLO because we are constantly measuring to make sure that customers are never impacted by CPU increases.</p>
    <div>
      <h3>Where to send the traffic?</h3>
      <a href="#where-to-send-the-traffic">
        
      </a>
    </div>
    <p>So now that we have a maximum threshold, we need to find the third CPU utilization threshold which isn’t used when calculating how much traffic to move - the acceptable threshold. When a data center is below this threshold, it has unused capacity which, as long as it isn’t forwarding traffic itself, is made available for other data centers to use when required. To work out how much each data center is able to receive, we use the same methodology as above, substituting target for acceptable:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1yHCxMMzytg6BnYdigXx1w/9f441adfb38cc474ab8580cdd1b5c72d/Screenshot-2023-09-18-at-22.16.48.png" />
            
            </figure><p>Therefore:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6A0qMzXEmTPhVl8KRIiTRO/7830d77baee83d779ff01ff3605f0f09/Screenshot-2023-09-18-at-22.17.36.png" />
            
            </figure><p>Subtracting the current CPU time from the acceptable CPU time gives us the amount of CPU time that a data center could accept:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7yQPGjUGnLWy9C9GGOzIRN/ad105de71360d03299039453b554059e/Screenshot-2023-09-18-at-22.18.16.png" />
            
            </figure><p>To find where to send traffic, Traffic Manager will find the available CPU time in all data centers, then it will order them by latency from the data center needing to move traffic. It moves through each of the data centers, using all available capacity based on the maximum thresholds before moving onto the next. When finding which plans to move, we move from the lowest priority plan to highest, but when finding where to send them, we move in the opposite direction.</p><p>To make this clearer let's use an example:</p><p>We need to move 1,000 CPU time from data center A, and we have the following usage per plan: Free: 500ms/s, Pro: 400ms/s, Business: 200ms/s, Enterprise: 1000ms/s.</p><p>We would move 100% of Free (500ms/s), 100% of Pro (400ms/s), 50% of Business (100ms/s), and 0% of Enterprise.</p><p>Nearby data centers have the following available CPU time: B: 300ms/s, C: 300ms/s, D: 1,000ms/s.</p><p>With latencies: A-B: 100ms, A-C: 110ms, A-D: 120ms.</p><p>Starting with the lowest latency and highest priority plan that requires action, we would be able to move all the Business CPU time to data center B and half of Pro. Next we would move onto data center C, and be able to move the rest of Pro, and 20% of Free. The rest of Free could then be forwarded to data center D. Resulting in the following action: Business: 50% → B, Pro: 50% → B, 50% → C, Free: 20% → C, 80% → D.</p>
    <div>
      <h3>Reverting actions</h3>
      <a href="#reverting-actions">
        
      </a>
    </div>
    <p>In the same way that Traffic Manager is constantly looking to keep data centers from going above the threshold, it is also looking to bring any forwarded traffic back into a data center that is actively forwarding traffic.</p><p>Above we saw how Traffic Manager works out how much traffic a data center is able to receive from another data center — it calls this the available CPU time. When there is an active move we use this available CPU time to bring back traffic to the data center — we always prioritize reverting an active move over accepting traffic from another data center.</p><p>When you put this all together, you get a system that is constantly measuring system and customer health metrics for every data center and spreading traffic around to make sure that each request can be served given the current state of our network. When we put all of these moves between data centers on a map, it looks something like this, a map of all Traffic Manager moves for a period of one hour. This map doesn’t show our full data center deployment, but it does show the data centers that are sending or receiving moved traffic during this period:</p><div>
  
</div>
<p></p><p>Data centers in red or yellow are under load and shifting traffic to other data centers until they become green, which means that all metrics are showing as healthy. The size of the circles represent how many requests are shifted from or to those data centers. Where the traffic is going is denoted by where the lines are moving. This is difficult to see at a world scale, so let’s zoom into the United States to see this in action for the same time period:</p><div>
  
</div>
<p></p><p>Here you can see Toronto, Detroit, New York, and Kansas City are unable to serve some requests due to hardware issues, so they will send those requests to Dallas, Chicago, and Ashburn until equilibrium is restored for users and data centers. Once data centers like Detroit are able to service all the requests they are receiving without needing to send traffic away, Detroit will gradually stop forwarding requests to Chicago until any issues in the data center are completely resolved, at which point it will no longer be forwarding anything. Throughout all of this, end users are online and are not impacted by any physical issues that may be happening in Detroit or any of the other locations sending traffic.</p>
    <div>
      <h3>Happy network, happy products</h3>
      <a href="#happy-network-happy-products">
        
      </a>
    </div>
    <p>Because Traffic Manager is plugged into the user experience, it is a fundamental component of the Cloudflare network: it keeps our products online and ensures that they’re as fast and reliable as they can be. It’s our real time load balancer, helping to keep our products fast by only shifting necessary traffic away from data centers that are having issues. Because less traffic gets moved, our products and services stay fast.</p><p>But Traffic Manager can also help keep our products online and reliable because they allow our products to predict where reliability issues may occur and preemptively move the products elsewhere. For example, Browser Isolation directly works with Traffic Manager to help ensure the uptime of the product. When you connect to a Cloudflare data center to create a hosted browser instance, Browser Isolation first asks Traffic Manager if the data center has enough capacity to run the instance locally, and if so, the instance is created right then and there. If there isn’t sufficient capacity available, Traffic Manager tells Browser Isolation which the closest data center with sufficient available capacity is, thereby helping Browser Isolation to provide the best possible experience for the user.</p>
    <div>
      <h3>Happy network, happy users</h3>
      <a href="#happy-network-happy-users">
        
      </a>
    </div>
    <p>At Cloudflare, we operate this huge network to service all of our different products and customer scenarios. We’ve built this network for resiliency: in addition to our MCP locations designed to reduce impact from a single failure, we are constantly shifting traffic around on our network in response to internal and external issues.</p><p>But that is our problem — not yours.</p><p>Similarly, when human beings had to fix those issues, it was customers and end users who would be impacted. To ensure that you’re always online, we’ve built a smart system that detects our hardware failures and preemptively balances traffic across our network to ensure it’s online and as fast as possible. This system works faster than any person — not only allowing our network engineers to sleep at night — but also providing a better, faster experience for all of our customers.</p><p>And finally: if these kinds of engineering challenges sound exciting to you, then please consider checking out the Traffic Engineering team's open position on Cloudflare’s <a href="https://cloudflare.com/careers/jobs">Careers</a> page!</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Traffic]]></category>
            <category><![CDATA[Routing]]></category>
            <category><![CDATA[Anycast]]></category>
            <category><![CDATA[Interconnection]]></category>
            <guid isPermaLink="false">lz1BR25h48nezzhD7C1Gr</guid>
            <dc:creator>David Tuber</dc:creator>
            <dc:creator>Luke Orden</dc:creator>
            <dc:creator>Gonçalo Grilo</dc:creator>
        </item>
        <item>
            <title><![CDATA[How Waiting Room makes queueing decisions on Cloudflare's highly distributed network]]></title>
            <link>https://blog.cloudflare.com/how-waiting-room-queues/</link>
            <pubDate>Wed, 20 Sep 2023 13:00:58 GMT</pubDate>
            <description><![CDATA[ We want to give you a behind the scenes look at how we have evolved the core mechanism of our product–namely, exactly how it kicks in to queue traffic in response to spikes ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/308ogSo9qOQp2ng3ve7spq/163e8201c4d426710ef2211237699c08/image3-7.png" />
            
            </figure><p>Almost three years ago, we <a href="/cloudflare-waiting-room/">launched Cloudflare Waiting Room</a> to protect our customers’ sites from overwhelming spikes in legitimate traffic that could bring down their sites. Waiting Room gives customers control over user experience even in times of high traffic by placing excess traffic in a customizable, on-brand waiting room, dynamically admitting users as spots become available on their sites. Since the launch of Waiting Room, we’ve continued to expand its functionality based on customer feedback with features like <a href="/waiting-room-random-queueing-and-custom-web-mobile-apps/">mobile app support</a>, <a href="/understand-the-impact-of-your-waiting-rooms-settings-with-waiting-room-analytics/">analytics</a>, <a href="/waiting-room-bypass-rules/">Waiting Room bypass rules</a>, and <a href="/tag/waiting-room/">more</a>.</p><p>We love announcing new features and solving problems for our customers by expanding the capabilities of Waiting Room. But, today, we want to give you a behind the scenes look at how we have evolved the core mechanism of our product–namely, exactly how it kicks in to queue traffic in response to spikes.</p>
    <div>
      <h2>How was the Waiting Room built, and what are the challenges?</h2>
      <a href="#how-was-the-waiting-room-built-and-what-are-the-challenges">
        
      </a>
    </div>
    <p>The diagram below shows a quick overview of where the Waiting room sits when a customer enables it for their website.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/e3jZQvH7ed5YAFbSYk5km/8866b3fe3f89ed1ac3f0b536d30b9d30/Waiting-Room-overview.png" />
            
            </figure><p>Waiting Room is built on <a href="https://workers.cloudflare.com/">Workers</a> that runs across a global network of Cloudflare data centers. The requests to a customer’s website can go to many different Cloudflare data centers. To optimize for minimal <a href="https://www.cloudflare.com/learning/performance/glossary/what-is-latency/">latency</a> and enhanced performance, these requests are routed to the data center with the most geographical proximity. When a new user makes a request to the host/path covered by the Waiting room, the waiting room worker decides whether to send the user to the origin or the waiting room. This decision is made by making use of the waiting room state which gives an idea of how many users are on the origin.</p><p>The waiting room state changes continuously based on the traffic around the world. This information can be stored in a central location or changes can get propagated around the world eventually. Storing this information in a central location can add significant latency to each request as the central location can be really far from where the request is originating from. So every data center works with its own waiting room state which is a snapshot of the traffic pattern for the website around the world available at that point in time. Before letting a user into the website, we do not want to wait for information from everywhere else in the world as that adds significant latency to the request. This is the reason why we chose not to have a central location but have a pipeline where changes in traffic get propagated eventually around the world.</p><p>This pipeline which aggregates the waiting room state in the background is built on Cloudflare <a href="/introducing-workers-durable-objects/">Durable Objects</a>. In 2021, we wrote a blog talking about <a href="/building-waiting-room-on-workers-and-durable-objects/">how the aggregation pipeline works</a> and the different design decisions we took there if you are interested. This pipeline ensures that every data center gets updated information about changes in traffic within a few seconds.</p><p>The Waiting room has to make a decision whether to send users to the website or queue them based on the state that it currently sees. This has to be done while making sure we queue at the right time so that the customer's website does not get overloaded. We also have to make sure we do not queue too early as we might be queueing for a falsely suspected spike in traffic. Being in a queue could cause some users to abandon going to the website. Waiting Room runs on every server in <a href="https://www.cloudflare.com/network/">Cloudflare’s network</a>, which spans over 300 cities in more than 100 countries. We want to make sure, for every new user, the decision whether to go to the website or the queue is made with minimal latency. This is what makes the decision of when to queue a hard question for the waiting room. In this blog, we will cover how we approached that tradeoff. Our algorithm has evolved to decrease the false positives while continuing to respect the customer’s set limits.</p>
    <div>
      <h2>How a waiting room decides when to queue users</h2>
      <a href="#how-a-waiting-room-decides-when-to-queue-users">
        
      </a>
    </div>
    <p>The most important factor that determines when your waiting room will start queuing is how you configured the traffic settings. There are two traffic limits that you will set when configuring a waiting room–<i>total active users</i> and <i>new users per minute</i>.The <i>total active users</i> is a target threshold for how many simultaneous users you want to allow on the pages covered by your waiting room. <i>New users per minute</i> defines the target threshold for the maximum rate of user influx to your website per minute. A sharp spike in either of these values might result in queuing. Another configuration that affects how we calculate the <i>total active users</i> is <i>session duration.</i> A user is considered active for <i>session duration</i> minutes since the request is made to any page covered by a waiting room.</p><p>The graph below is from one of our internal monitoring tools for a customer and shows a customer's traffic pattern for 2 days. This customer has set their limits, <i>new users per minute</i> and <i>total active users</i> to 200 and 200 respectively.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ldSHbmG07jQ9qRikiy9Yh/500ddc98a204322415592acdddefb91d/Screen-Shot-2023-09-11-at-10.30.21-AM.png" />
            
            </figure><p>If you look at their traffic you can see that users were queued on September 11th around 11:45. At that point in time, the <i>total active users</i> was around 200. As the <i>total active users</i> ramped down (around 12:30)<i>,</i> the queued users progressed to 0. The queueing started again on September 11th around 15:00 when total active users got to 200. The users that were queued around this time ensured that the traffic going to the website is around the limits set by the customer.</p><p>Once a user gets access to the website, we give them an encrypted <a href="https://www.cloudflare.com/learning/privacy/what-are-cookies/">cookie</a> which indicates they have already gained access. The contents of the cookie can look like this.</p>
            <pre><code>{  
  "bucketId": "Mon, 11 Sep 2023 11:45:00 GMT",
  "lastCheckInTime": "Mon, 11 Sep 2023 11:45:54 GMT",
  "acceptedAt": "Mon, 11 Sep 2023 11:45:54 GMT"
}</code></pre>
            <p>The cookie is like a ticket which indicates entry to the waiting room.The <i>bucketId</i> indicates which cluster of users this user is part of. The <i>acceptedAt</i> time and <i>lastCheckInTime</i> indicate when the last interaction with the workers was. This information can ensure if the ticket is valid for entry or not when we compare it with the <i>session duration</i> value that the customer sets while configuring the waiting room. If the cookie is valid, we let the user through which ensures users who are on the website continue to be able to browse the website. If the cookie is invalid, we create a new cookie treating the user as a new user and if there is queueing happening on the website they get to the back of the queue. In the next section let us see how we decide when to queue those users.</p><p>To understand this further, let's see what the contents of the waiting room state are. For the customer we discussed above, at the time "Mon, 11 Sep 2023 11:45:54 GMT", the state could look like this.</p>
            <pre><code>{  
  "activeUsers": 50,
}</code></pre>
            <p>As mentioned above the customer’s configuration has <i>new users per minute</i> and t_otal active users_ equal to 200 and 200 respectively.</p><p>So the state indicates that there is space for the new users as there are only 50 active users when it's possible to have 200. So there is space for another 150 users to go in. Let's assume those 50 users could have come from two data centers San Jose (20 users) and London (30 users). We also keep track of the number of workers that are active across the globe as well as the number of workers active at the data center in which the state is calculated. The state key below could be the one calculated at San Jose.</p>
            <pre><code>{  
  "activeUsers": 50,
  "globalWorkersActive": 10,
  "dataCenterWorkersActive": 3,
  "trafficHistory": {
    "Mon, 11 Sep 2023 11:44:00 GMT": {
       San Jose: 20/200, // 10%
       London: 30/200, // 15%
       Anywhere: 150/200 // 75%
    }
  }
}</code></pre>
            <p>Imagine at the time "<code>Mon, 11 Sep 2023 11:45:54 GMT</code>", we get a request to that waiting room at a datacenter in San Jose.</p><p>To see if the user that reached San Jose can go to the origin we first check the traffic history in the past minute to see the distribution of traffic at that time. This is because a lot of websites are popular in certain parts of the world. For a lot of these websites the traffic tends to come from the same data centers.</p><p>Looking at the traffic history for the minute "<code>Mon, 11 Sep 2023 11:44:00 GMT</code>" we see San Jose has 20 users out of 200 users going there (10%) at that time. For the current time "<code>Mon, 11 Sep 2023 11:45:54 GMT</code>" we divide the slots available at the website at the same ratio as the traffic history in the past minute. So we can send 10% of 150 slots available from San Jose which is 15 users. We also know that there are three active workers as "<code>dataCenterWorkersActive</code>" is <code>3</code>.</p><p>The number of slots available for the data center is divided evenly among the workers in the data center. So every worker in San Jose can send 15/3 users to the website. If the worker that received the traffic has not sent any users to the origin for the current minute they can send up to <i>five</i> users (15/3).</p><p>At the same time ("<code>Mon, 11 Sep 2023 11:45:54 GMT</code>"), imagine a request goes to a data center in Delhi. The worker at the data center in Delhi checks the trafficHistory and sees that there are no slots allotted for it. For traffic like this we have reserved the Anywhere slots as we are really far away from the limit.</p>
            <pre><code>{  
  "activeUsers":50,
  "globalWorkersActive": 10,
  "dataCenterWorkersActive": 1,
  "trafficHistory": {
    "Mon, 11 Sep 2023 11:44:00 GMT": {
       San Jose: 20/200, // 10%
       London: 30/200, // 15%
       Anywhere: 150/200 // 75%
    }
  }
}</code></pre>
            <p>The <code>Anywhere</code> slots are divided among all the active workers in the globe as any worker around the world can take a part of this pie. 75% of the remaining 150 slots which is 113.</p><p>The state key also keeps track of the number of workers (<code>globalWorkersActive</code>) that have spawned around the world. The Anywhere slots allotted are divided among all the active workers in the world if available. <code>globalWorkersActive</code> is 10 when we look at the waiting room state. So every active worker can send as many as 113/10 which is approximately 11 users. So the first 11 users that come to a worker in the minute <code>Mon, 11 Sep 2023 11:45:00 GMT</code> gets admitted to the origin. The extra users get queued. The extra reserved slots (5) in San Jose for minute  <code>Mon, 11 Sep 2023 11:45:00 GMT</code> discussed before ensures that we can admit up to 16(5 + 11) users from a worker from San Jose to the website.</p>
    <div>
      <h2>Queuing at the worker level can cause users to get queued before the slots available for the data center</h2>
      <a href="#queuing-at-the-worker-level-can-cause-users-to-get-queued-before-the-slots-available-for-the-data-center">
        
      </a>
    </div>
    <p>As we can see from the example above, we decide whether to queue or not at the worker level. The number of new users that go to workers around the world can be non-uniform. To understand what can happen when there is non-uniform distribution of traffic to two workers, let us look at the diagram below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2I3CYq6IbnjE7T1A4yEOC1/513183137efaa278314be172c9ba549d/Side-effect-of-dividing-slots-at-worker-level.png" />
            
            </figure><p>Imagine the slots available for a data center in San Jose are <i>ten</i>. There are two workers running in San Jose. <i>Seven</i> users go to worker1 and <i>one</i> user goes to worker2. In this situation worker1 will let in <i>five</i> out of the <i>seven</i> workers to the website and <i>two</i> of them get queued as worker1 only has <i>five</i> slots available. The <i>one</i> user that shows up at worker2 also gets to go to the origin. So we queue <i>two</i> users, when in reality <i>ten</i> users can get sent from the datacenter San Jose when only <i>eight</i> users show up.</p><p>This issue while dividing slots evenly among workers results in queueing before a waiting room’s configured traffic limits, typically within 20-30% of the limits set. This approach has advantages which we will discuss next. We have made changes to the approach to decrease the frequency with which queuing occurs outside that 20-30% range, queuing as close to limits as possible, while still ensuring Waiting Room is prepared to catch spikes. Later in this blog, we will cover how we achieved this by updating how we allocate and count slots.</p>
    <div>
      <h3>What is the advantage of workers making these decisions?</h3>
      <a href="#what-is-the-advantage-of-workers-making-these-decisions">
        
      </a>
    </div>
    <p>The example above talked about how a worker in San Jose and Delhi makes decisions to let users through to the origin. The advantage of making decisions at the worker level is that we can make decisions without any significant latency added to the request. This is because to make the decision, there is no need to leave the data center to get information about the waiting room as we are always working with the state that is currently available in the data center. The queueing starts when the slots run out within the worker. The lack of additional latency added enables the customers to turn on the waiting room all the time without worrying about extra latency to their users.</p><p>Waiting Room’s number one priority is to ensure that customer’s sites remain up and running at all times, even in the face of unexpected and overwhelming traffic surges. To that end, it is critical that a waiting room prioritizes staying near or below traffic limits set by the customer for that room. When a spike happens at one data center around the world, say at San Jose, the local state at the data center will take a few seconds to get to Delhi.</p><p>Splitting the slots among workers ensures that working with slightly outdated data does not cause the overall limit to be exceeded by an impactful amount. For example, the <code>activeUsers</code> value can be 26 in the San Jose data center and 100 in the other data center where the spike is happening. At that point in time, sending extra users from Delhi may not overshoot the overall limit by much as they only have a part of the pie to start with in Delhi. Therefore, queueing before overall limits are reached is part of the design to make sure your overall limits are respected. In the next section we will cover the approaches we implemented to queue as close to limits as possible without increasing the risk of exceeding traffic limits.</p>
    <div>
      <h2>Allocating more slots when traffic is low relative to waiting room limits</h2>
      <a href="#allocating-more-slots-when-traffic-is-low-relative-to-waiting-room-limits">
        
      </a>
    </div>
    <p>The first case we wanted to address was queuing that occurs when traffic is far from limits. While rare and typically lasting for one refresh interval (20s) for the end users who are queued, this was our first priority when updating our queuing algorithm. To solve this, while allocating slots we looked at the utilization (how far you are from traffic limits) and allotted more slots when traffic is really far away from the limits. The idea behind this was to prevent the queueing that happens at lower limits while still being able to readjust slots available per worker when there are more users on the origin.</p><p>To understand this let's revisit the example where there is non-uniform distribution of traffic to two workers. So two workers similar to the one we discussed before are shown below. In this case the utilization is low (10%). This means we are far from the limits. So the slots allocated(8) are closer to the <code>slotsAvailable</code> for the datacenter San Jose which is 10. As you can see in the diagram below, all the eight users that go to either worker get to reach the website with this modified slot allocation as we are providing more slots per worker at lower utilization levels.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7zNp1o6DEAbGL4GSYjUkeJ/1bc9bdf44861eb0025a0fe49ce45ae2a/Division-of-slots-among-workers-at-lower-utilization.png" />
            
            </figure><p>The diagram below shows how the slots allocated per worker changes with utilization (how far you are away from limits). As you can see here, we are allocating more slots per worker at lower utilization. As the utilization increases, the slots allocated per worker decrease as it’s getting closer to the limits, and we are better prepared for spikes in traffic. At 10% utilization every worker gets close to the slots available for the data center. As the utilization is close to 100% it becomes close to the slots available divided by worker count in the data center.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2qy2IXaKqoER8zkDRL9mAZ/2de5767fa86bc57ccc1d428b26269cef/Alloting-more-slots-at-lower-limits.png" />
            
            </figure>
    <div>
      <h3>How do we achieve more slots at lower utilization?</h3>
      <a href="#how-do-we-achieve-more-slots-at-lower-utilization">
        
      </a>
    </div>
    <p>This section delves into the mathematics which helps us get there. If you are not interested in these details, meet us at the “Risk of over provisioning” section.</p><p>To understand this further, let's revisit the previous example where requests come to the Delhi data center. The <code>activeUsers</code> value is 50, so utilization is 50/200 which is around 25%.</p>
            <pre><code>{
  "activeUsers": 50,
  "globalWorkersActive": 10,
  "dataCenterWorkersActive": 1,
  "trafficHistory": {
    "Mon, 11 Sep 2023 11:44:00 GMT": {
       San Jose: 20/200, // 10%
       London: 30/200, // 15%
       Anywhere: 150/200 // 75%
    }
  }
}</code></pre>
            <p>The idea is to allocate more slots at lower utilization levels. This ensures that customers do not see unexpected queueing behaviors when traffic is far away from limits. At time <code>Mon, 11 Sep 2023 11:45:54 GMT</code> requests to Delhi are at 25% utilization based on the local state key.</p><p>To allocate more slots to be available at lower utilization we added a <code>workerMultiplier</code> which moves proportionally to the utilization. At lower utilization the multiplier is lower and at higher utilization it is close to one.</p>
            <pre><code>workerMultiplier = (utilization)^curveFactor
adaptedWorkerCount = actualWorkerCount * workerMultiplier</code></pre>
            <p><code>utilization</code> - how far away from the limits you are.</p><p><code>curveFactor</code> - is the exponent which can be adjusted which decides how aggressive we are with the distribution of extra budgets at lower worker counts. To understand this let's look at the graph of how y = x and y = x^2 looks between values 0 and 1.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4wgTahQXjs2Heu9fW2jOgG/56f26b2e0bcd048dd4a2a7b28bdaef38/Graph-for-y-x-curveFactor.png" />
            
            </figure><p>The graph for y=x is a straight line passing through (0, 0) and (1, 1).</p><p>The graph for <code>y=x^2</code> is a curved line where y increases slower than <code>x</code> when <code>x &lt; 1</code> and passes through (0, 0) and (1, 1)</p><p>Using the concept of how the curves work, we derived the formula for <code>workerCountMultiplier</code> where <code><i>y=workerCountMultiplier</i></code><i>,</i> <code><i>x=utilization</i></code> and <code><i>curveFactor</i></code> is the power which can be adjusted which decides how aggressive we are with the distribution of extra budgets at lower worker counts. When <code>curveFactor</code> is 1, the <code>workerMultiplier</code> is equal to the utilization.</p><p>Let's come back to the example we discussed before and see what the value of the curve factor will be. At time <code>Mon, 11 Sep 2023 11:45:54 GMT</code> requests to Delhi are at 25% utilization based on the local state key. The Anywhere slots are divided among all the active workers in the globe as any worker around the world can take a part of this pie. i.e. 75% of the remaining 150 slots (113).</p><p><code>globalWorkersActive</code> is 10 when we look at the waiting room state. In this case we do not divide the 113 slots by 10 but instead divide by the adapted worker count which is <code>globalWorkersActive ***** workerMultiplier</code>. If <code>curveFactor</code> is <code>1</code>, the <code>workerMultiplier</code> is equal to the utilization which is at 25% or 0.25.</p><p>So effective <code>workerCount</code> = 10 * 0.25 = 2.5</p><p>So, every active worker can send as many as 113/2.5 which is approximately 45 users. The first 45 users that come to a worker in the minute <code>Mon, 11 Sep 2023 11:45:00 GMT</code> gets admitted to the origin. The extra users get queued.</p><p>Therefore, at lower utilization (when traffic is farther from the limits) each worker gets more slots. But, if the sum of slots are added up, there is a higher chance of exceeding the overall limit.</p>
    <div>
      <h3>Risk of over provisioning</h3>
      <a href="#risk-of-over-provisioning">
        
      </a>
    </div>
    <p>The method of giving more slots at lower limits decreases the chances of queuing when traffic is low relative to traffic limits. However, at lower utilization levels a uniform spike happening around the world could cause more users to go into the origin than expected. The diagram below shows the case where this can be an issue. As you can see the slots available are <i>ten</i> for the data center. At 10% utilization we discussed before, each worker can have <i>eight</i> slots each. If <i>eight</i> users show up at one worker and <i>seven</i> show up at another, we will be sending <i>fifteen</i> users to the website when only <i>ten</i> are the maximum available slots for the data center.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3aKrVwAvh40LjZGBcGl43R/2736425861cbc5ff8266c0aa7aa64a88/Risk-of-over-provisioning-at-lower-utilization.png" />
            
            </figure><p>With the range of customers and types of traffic we have, we were able to see cases where this became a problem. A traffic spike from low utilization levels could cause overshooting of the global limits. This is because we are over provisioned at lower limits and this increases the risk of significantly exceeding traffic limits. We needed to implement a safer approach which would not cause limits to be exceeded while also decreasing the chance of queueing when traffic is low relative to traffic limits.</p><p>Taking a step back and thinking about our approach, one of the assumptions we had was that the traffic in a data center directly correlates to the worker count that is found in a data center. In practice what we found is that this was not true for all customers. Even if the traffic correlates to the worker count, the new users going to the workers in the data centers may not correlate. This is because the slots we allocate are for new users but the traffic that a data center sees consists of both users who are already on the website and new users trying to go to the website.</p><p>In the next section we are talking about an approach where worker counts do not get used and instead workers communicate with other workers in the data center. For that we introduced a new service which is a durable object counter.</p>
    <div>
      <h2>Decrease the number of times we divide the slots by introducing Data Center Counters</h2>
      <a href="#decrease-the-number-of-times-we-divide-the-slots-by-introducing-data-center-counters">
        
      </a>
    </div>
    <p>From the example above, we can see that overprovisioning at the worker level has the risk of using up more slots than what is allotted for a data center. If we do not over provision at low levels we have the risk of queuing users way before their configured limits are reached which we discussed first. So there has to be a solution which can achieve both these things.</p><p>The overprovisioning was done so that the workers do not run out of slots quickly when an uneven number of new users reach a bunch of workers. If there is a way to communicate between two workers in a data center, we do not need to divide slots among workers in the data center based on worker count. For that communication to take place, we introduced counters. Counters are a bunch of small durable object instances that do counting for a set of workers in the data center.</p><p>To understand how it helps with avoiding usage of worker counts, let's check the diagram below. There are two workers talking to a <i>Data Center Counter</i> below. Just as we discussed before, the workers let users through to the website based on the waiting room state. The count of the number of users let through was stored in the memory of the worker before. By introducing counters, it is done in the <i>Data Center Counter</i>. Whenever a new user makes a request to the worker, the worker talks to the counter to know the current value of the counter. In the example below for the first new request to the worker the counter value received is 9. When a data center has 10 slots available, that will mean the user can go to the website. If the next worker receives a new user and makes a request just after that, it will get a value 10 and based on the slots available for the worker, the user will get queued.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ttIdi7gwzmK4ENeqkIGO0/108c8831de2691504c4667bbc6180fcc/Counters-helping-workers-communicate-with-each-other.png" />
            
            </figure><p>The <i>Data Center Counter</i> acts as a point of synchronization for the workers in the waiting room. Essentially, this enables the workers to talk to each other without really talking to each other directly. This is similar to how a ticketing counter works. Whenever one worker lets someone in, they request tickets from the counter, so another worker requesting the tickets from the counter will not get the same ticket number. If the ticket value is valid, the new user gets to go to the website. So when different numbers of new users show up at workers, we will not over allocate or under allocate slots for the worker as the number of slots used is calculated by the counter which is for the data center.</p><p>The diagram below shows the behavior when an uneven number of new users reach the workers, one gets <i>seven</i> new users and the other worker gets <i>one</i> new user. All <i>eight</i> users that show up at the workers in the diagram below get to the website as the slots available for the data center is <i>ten</i> which is below <i>ten</i>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/bais5OnxQpewoeNM2T81H/b2693f9d527c65183299e5bbe778d976/Uneven-number-of-requests-to-Workers-does-not-cause-queueing.png" />
            
            </figure><p>This also does not cause excess users to get sent to the website as we do not send extra users when the counter value equals the <code>slotsAvailable</code> for the data center. Out of the <i>fifteen</i> users that show up at the workers in the diagram below <i>ten</i> will get to the website and <i>five</i> will get queued which is what we would expect.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7IF1Ze4p1TvZM9YUfCLyla/ba620e498641a3006eedc6200e0e3c55/Risk-of-over-provisioning-at-lower-utilization-also-does-not-exist-as-counters-help-Workers-communicate-with-each-other.png" />
            
            </figure><p>Risk of over provisioning at lower utilization also does not exist as counters help workers to communicate with each other.</p><p>To understand this further, let's look at the previous example we talked about and see how it works with the actual waiting room state.</p><p>The waiting room state for the customer is as follows.</p>
            <pre><code>{  
  "activeUsers": 50,
  "globalWorkersActive": 10,
  "dataCenterWorkersActive": 3,
  "trafficHistory": {
    "Mon, 11 Sep 2023 11:44:00 GMT": {
       San Jose: 20/200, // 10%
       London: 30/200, // 15%
       Anywhere: 150/200 // 75%
    }
  }
}</code></pre>
            <p>The objective is to not divide the slots among workers so that we don’t need to use that information from the state. At time <code>Mon, 11 Sep 2023 11:45:54 GMT</code> requests come to San Jose. So, we can send 10% of 150 slots available from San Jose which is 15.</p><p>The durable object counter at San Jose keeps returning the counter value it is at right now for every new user that reaches the data center. It will increment the value by 1 after it returns to a worker. So the first 15 new users that come to the worker get a unique counter value. If the value received for a user is less than 15 they get to use the slots at the data center.</p><p>Once the slots available for the data center runs out, the users can make use of the slots allocated for Anywhere data-centers as these are not reserved for any particular data center. Once a worker in San Jose gets a ticket value that says 15, it realizes that it's not possible to go to the website using the slots from San Jose.</p><p>The Anywhere slots are available for all the active workers in the globe i.e. 75% of the remaining 150 slots (113). The Anywhere slots are handled by a durable object that workers from different data centers can talk to when they want to use Anywhere slots. Even if 128 (113 + 15) users end up going to the same worker for this customer we will not queue them. This increases the ability of Waiting Room to handle an uneven number of new users going to workers around the world which in turn helps the customers to queue close to the configured limits.</p>
    <div>
      <h3>Why do counters work well for us?</h3>
      <a href="#why-do-counters-work-well-for-us">
        
      </a>
    </div>
    <p>When we built the Waiting Room, we wanted the decisions for entry into the website to be made at the worker level itself without talking to other services when the request is in flight to the website. We made that choice to avoid adding latency to user requests. By introducing a synchronization point at a durable object counter, we are deviating from that by introducing a call to a durable object counter.</p><p>However, the durable object for the data center stays within the same data center. This leads to minimal additional latency which is usually less than 10 ms. For the calls to the durable object that handles Anywhere data centers, the worker may have to cross oceans and long distances. This could cause the latency to be around 60 or 70 ms in those cases. The 95th percentile values shown below are higher because of calls that go to farther data centers.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5LC6pdXV2rZxZAntvU36Bs/fa9c714cd8bbad0d2b6fed0a35873f7d/1Dr9LuESmHPXU4nQlr_9WIncDSE9uXcbHA6qevspl.png" />
            
            </figure><p>The design decision to add counters adds a slight extra latency for new users going to the website. We deemed the trade-off acceptable because this reduces the number of users that get queued before limits are reached. In addition, the counters are only required when new users try to go into the website. Once new users get to the origin, they get entry directly from workers as the proof of entry is available in the cookies that the customers come with, and we can let them in based on that.</p><p>Counters are really simple services which do simple counting and do nothing else. This keeps the memory and CPU footprint of the counters minimal. Moreover, we have a lot of counters around the world handling the coordination between a subset of workers.This helps counters to successfully handle the load for the synchronization requirements from the workers. These factors add up to make counters a viable solution for our use case.</p>
    <div>
      <h2>Summary</h2>
      <a href="#summary">
        
      </a>
    </div>
    <p>Waiting Room was designed with our number one priority in mind–to ensure that our customers’ sites remain up and running, no matter the volume or ramp up of legitimate traffic. Waiting Room runs on every server in Cloudflare’s network, which spans over 300 cities in more than 100 countries. We want to make sure, for every new user, the decision whether to go to the website or the queue is made with minimal latency and is done at the right time. This decision is a hard one as queuing too early at a data center can cause us to queue earlier than the customer set limits. Queuing too late can cause us to overshoot the customer set limits.</p><p>With our initial approach where we divide slots among our workers evenly we were sometimes queuing too early but were pretty good at respecting customer set limits. Our next approach of giving more slots at low utilization (low traffic levels compared to customer limits) ensured that we did better at the cases where we queued earlier than the customer set limits as every worker has more slots to work with at each worker. But as we have seen, this made us more likely to overshoot when a sudden spike in traffic occurred after a period of low utilization.</p><p>With counters we are able to get the best of both worlds as we avoid the division of slots by worker counts. Using counters we are able to ensure that we do not queue too early or too late based on the customer set limits. This comes at the cost of a little bit of latency to every request from a new user which we have found to be negligible and creates a better user experience than getting queued early.</p><p>We keep iterating on our approach to make sure we are always queuing people at the right time and above all protecting your website. As more and more customers are using the waiting room, we are learning more about different types of traffic and that is helping the product be better for everyone.</p> ]]></content:encoded>
            <category><![CDATA[Waiting Room]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Durable Objects]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <guid isPermaLink="false">378OAooWIn9X080mpldET2</guid>
            <dc:creator>George Thomas</dc:creator>
        </item>
        <item>
            <title><![CDATA[How the Cloudflare global network optimizes for system reboots during low-traffic periods]]></title>
            <link>https://blog.cloudflare.com/how-the-cloudflare-global-network-optimizes-for-system-reboots-during-low-traffic-periods/</link>
            <pubDate>Wed, 12 Jul 2023 13:00:20 GMT</pubDate>
            <description><![CDATA[ We run a wide fleet of machines on the Cloudflare global network. This post describes how we minimize customer disruption during large-scale machine reboots using math! ]]></description>
            <content:encoded><![CDATA[ <p></p><p>To facilitate the huge scale of Cloudflare’s customer base, we maintain data centers which span more than 300 cities in over 100 countries, including approximately 30 locations in Mainland China.</p><p>The Cloudflare global network is built to be continuously updated in a zero downtime manner, but some changes may need a server reboot to safely take effect. To enable this, we have mechanisms for the whole fleet to automatically reboot with changes gated on a unique identifier for the reboot cycle. Each data center has a <b>maintenance window</b>, which is a time period - usually a couple of hours - during which reboots are permitted.</p><p>We take our customer experience very seriously, and hence we have several mechanisms to ensure that disruption to customer traffic does not occur. One example is <a href="/unimog-cloudflares-edge-load-balancer/">Unimog</a>, our in-house load balancer that spreads load across the servers in a data center, ensuring that there is no disruption when a server is taken out for routine maintenance.</p><p>The SRE team decided to further reduce risk by only allowing reboots in a data center when the customer traffic is at the lowest. We also needed to automate the existing manual process for determining the window - eliminating toil.</p><p>In this post, we’ll discuss how the team improved this manual process and automated the determination of these windows using a trigonometric function - sinusoidal wave fitting.</p>
    <div>
      <h2>When is the best time to reboot?</h2>
      <a href="#when-is-the-best-time-to-reboot">
        
      </a>
    </div>
    <p>Thanks to <a href="/unimog-cloudflares-edge-load-balancer/">how efficient our load-balancing framework is</a> within a data center, technically we could proceed to schedule reboots throughout the day with zero impact to traffic flowing through the data center. However, operationally the management is simplified by requiring reboots take place between certain times for each data center. It both acts as a rate-limiter to avoid rebooting all servers in our larger data centers in a single day, and makes remediating any unforeseen issues that arise during the reboots more straightforward, as issues can be caught within the first batch of reboots.</p><p>One of the first steps is to determine the time window during which we are going to allow these reboots to take place; choosing the relative low-traffic period for a data center makes the most sense for obvious reasons. In the past, these low-traffic windows were found manually by humans reviewing historical traffic trends present in our metrics; it was SRE who were responsible for creating and maintaining the definition of these windows, which became particularly toilsome:</p><ol><li><p>Traffic trends are always changing, requiring increasingly frequent reviews of maintenance hours.</p></li><li><p>We move quickly at Cloudflare, there is always a data center in a state of provisioning, making it difficult to keep maintenance windows up-to-date.</p></li><li><p>The system was inflexible, and provided no dynamic decision-making.</p></li><li><p>This responsibility became SRE toil as it was repetitive, process-based work that could and should be automated.</p></li></ol>
    <div>
      <h2>Time to be more efficient</h2>
      <a href="#time-to-be-more-efficient">
        
      </a>
    </div>
    <p>We quickly realized that we needed to make this process more efficient using automation. An ideal solution would be one that was accurate, easy to maintain, re-usable, and could be consumed by other teams.</p><p>A theoretical solution to this was <b>sine-fitting</b> on the CPU pattern of the data center over a configurable period. e.g. two weeks. This method is a way to transform the pattern into a theoretical sinusoidal wave as shown in the image below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6m0REdheEVhO4W3BsS5HFL/b1b0b057c1f1dfd355e74d65d3ce5e48/bkk05.png" />
            
            </figure><p>With a sine wave, the most common troughs can be determined. The periods where these troughs occur are then used as options for the maintenance window.</p>
    <div>
      <h2>Sinusoidal wave theory - the secret sauce</h2>
      <a href="#sinusoidal-wave-theory-the-secret-sauce">
        
      </a>
    </div>
    <p>We think math is fun and were excited to see how this held up in practice. To implement the logic and tests, we needed to understand the theory. This section details the important bits for anyone that is interested in implementing this for their maintenance cycles as well.</p><p>The image below shows a theoretical representation of a sine wave. It is represented by the mathematical function y(t) = Asin(2πft + φ) where A = Amplitude, f = Frequency, t = Time and φ = Phase.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Lz6pTBIAuP5fumgeqQEP5/65353694941e554cacd8e05990deb69f/sine.drawio--4-.png" />
            
            </figure><p>In practice, various programming language packages exist to fit an arbitrary dataset on a curve. For example, Python has the <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html">scipy curve_fit function</a>.</p><p>We used Python and to make the result more accurate, it is recommended to include arbitrary values as initial guesses. These are described below;</p><p><b>Amplitude</b>: This is the distance from the peak/valley to the time axis, and is approximated as the standard deviation multiplied by √2. The standard deviation represents the variability in the data points, and for a sine wave that varies between -1 and +1, the standard deviation is approximately 0.707 (or 1/√2). Therefore, by multiplying the standard deviation of the data by √2, we can represent an approximation of the amplitude.</p><p><b>Frequency</b>: This is the number of cycles (time periods) in one second. We are concerned with the daily CPU pattern, meaning that the guess should be one full wave every 24 hours (i.e. 1/86400).</p><p><b>Phase</b>: This is the position of the wave at T=0. No guess is needed for this.</p><p><b>Offset</b>: To fit the sine wave on the CPU values, we need to shift upwards by the offset. This offset is the mean of the CPU values.</p><p>Here’s a basic example of how it can be implemented in Python:</p>
            <pre><code>timestamps = numpy.array(timestamps)
cpu = numpy.array(cpu)
guess_freq = 1 / 86400  # 24h periodicity
guess_amp = numpy.std(cpu) * 2.0**0.5
guess_offset = numpy.mean(cpu)
guess = numpy.array([guess_amp, 2.0 * numpy.pi * guess_freq, 0.0, guess_offset])
 
def sinfunc(timestamps, amplitude, frequency, phase, offset):
    return amplitude * numpy.sin(frequency * timestamps + phase) + offset
 
amplitude, frequency, phase, offset, _ = scipy.optimize.curve_fit(
    sinfunc, timestamps, cpu, p0=guess, maxfev=2000
)</code></pre>
            
    <div>
      <h2>Applying the theory</h2>
      <a href="#applying-the-theory">
        
      </a>
    </div>
    <p>With the theory understood, we implemented this logic in our reboot system. To determine the window, the reboot system queries <a href="/tag/prometheus/">Prometheus</a> for the data center CPU over a configurable period and attempts to fit a curve on the resultant pattern.</p><p>If there’s an accurate enough fit, the window is cached in Consul along with other metadata. Otherwise, fallback logic is implemented. For various reasons, some data centers might not have enough data for a fit at that moment. For example, a data center which was only recently provisioned and hasn’t served enough traffic yet.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5CrPBsJwkVqmvL4NYkcTsK/35b0bbf59fce37c7fe0efc461e1f562f/Frame-5269.png" />
            
            </figure><p>When a server requests to reboot, the system checks if the current time is within the maintenance window first, before running other pre-flight checks. In most cases the window already exists because of the prefetch mechanism implemented, but when it doesn’t due to Consul session expiry or some other reason, it is computed using the CPU data in Prometheus.</p><p>The considerations in this phase were:</p><p><b>Caching</b>: Calculation of the window should only be done over a pre-decided validity period. To achieve this we store the information in a Consul KV, along with a session lock that expires after the validity period. We <a href="/how-we-use-hashicorp-nomad/">have mentioned in the past</a> that we use Consul as a service-discovery and key-value storage mechanism. This is an example of the latter.</p><p><b>Pre-fetch</b>: In practice, it makes sense to control when this computation happens. There are several options but the most efficient was to implement a pre-fetch of this window on startup of the reboot system.</p><p><b>Observability</b>: We exported a couple of metrics to Prometheus, which help us understand the decisions being made and any errors we need to address. We also export the maintenance window itself for consumption by other automated systems and teams.</p>
    <div>
      <h2>How accurate is this fit?</h2>
      <a href="#how-accurate-is-this-fit">
        
      </a>
    </div>
    <p>Most load patterns fit into the sine wave, but there are some edge cases occasionally. e.g. a smaller data center that has a constant CPU. In those cases we have fallback mechanisms, but it also got us thinking about how to determine the accuracy of each fit.</p><p>With accuracy data we can make smarter decisions about accepting the automatic window, track regressions and unearth data centers with unexpected patterns. The theoretical solution here is referred to as the <b>goodness of fit</b>.</p><p><a href="https://youtu.be/Jl-Ye38qkRc">Curve fitting in Python with curve_fit</a> describes curve fitting and calculating the chi-squared value. The formula for a goodness of fit chi-squared test in the image below:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5H29tgQrHcJFXZg2BSAhYA/e61c1354768aaf36eadcfdc2e0d6e60e/Untitled.png" />
            
            </figure><p>The different values are the observed (Yi), expected (f(Xi)) and uncertainty. In this theory, the closer the chi-square value to the length of the sample, the better the fit is. Chi-squared values that are a lot smaller than the length represent an overestimated uncertainty and much larger represent a bad fit.</p><p>This is implemented with a simple formula:</p>
            <pre><code>def goodness_of_fit(observed, expected):
 
    chisq = numpy.sum(((observed - expected)/ numpy.std(observed)) ** 2)
 
    # Present the chisq value percentage relative to the sample length
    n = len(observed)
    return ((n - chisq) / n) * 100</code></pre>
            <p>The observed result of this is that the smaller the chi-squared, the more accurate the fit and vice versa. Hence we can provide a fit percentage of the difference between the length and the chi-squared.</p><p>There are three main types of fit, as shown in the images below.</p>
    <div>
      <h3>Bad Fit</h3>
      <a href="#bad-fit">
        
      </a>
    </div>
    <p>These data centers do not exhibit a sinusoidal pattern and the maintenance window can only be determined arbitrarily. This is common in test data centers which do not handle customer traffic. In these cases, it makes sense to turn off load-based reboots and use an arbitrary window. In these cases, it is common to require faster reboots on a different schedule to catch any potential issues early.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5d7CxZfSQkvubSUdK8DlQA/00f849b422a0383bbd051741758ab75d/bgw05.png" />
            
            </figure>
    <div>
      <h3>Skewed Fit</h3>
      <a href="#skewed-fit">
        
      </a>
    </div>
    <p>These data centers exhibit sinusoidal traffic patterns but are a bit skewed, with some smaller troughs within the wave cycle. The troughs (and hence the windows) are still correct, but the accuracy of fit is reduced.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Kh1ulRPX7V1vWq9BufT8r/7ded85df831ae8c06a4c82674f59d7ec/alg01.png" />
            
            </figure>
    <div>
      <h3>Great Fit</h3>
      <a href="#great-fit">
        
      </a>
    </div>
    <p>These are data centers with very clear patterns and great fits. This is the ideal scenario and most fall into this category.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/37lKmcTlLr9hdMP59WNlDJ/4bfed02a2a07be2a6ba0ca96823e5961/blr02.png" />
            
            </figure>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We will continue to iterate on this to make it more accurate, and provide more ways to consume the information. We have a variety of maintenance use-cases that cut across multiple organizations, and it’s exciting to see the information used more widely besides reboots. For example, teams can use maintenance windows to make automated decisions in downstream services such as running compute-intensive background tasks only in those periods.</p>
    <div>
      <h2>I want to do this type of work</h2>
      <a href="#i-want-to-do-this-type-of-work">
        
      </a>
    </div>
    <p>If you found this post very interesting and want to contribute, take a look at our <a href="https://www.cloudflare.com/en-gb/careers/">careers page</a> for open positions! We’d love to have a conversation with you.  </p> ]]></content:encoded>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">1Ok6rETpMBSorWxiXIQrrJ</guid>
            <dc:creator>Opeyemi Onikute</dc:creator>
            <dc:creator>Nick Rhodes</dc:creator>
        </item>
        <item>
            <title><![CDATA[The day my ping took countermeasures]]></title>
            <link>https://blog.cloudflare.com/the-day-my-ping-took-countermeasures/</link>
            <pubDate>Tue, 11 Jul 2023 13:05:00 GMT</pubDate>
            <description><![CDATA[ Ping developers clearly put some thought into that. I wondered how far they went. Did they handle clock changes in both directions? Are the bad measurements excluded from the final statistics? How do they test the software? ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3n0xGuyOEFmzVNvoE2XTh0/d14bafdc7ac93fbc0bb1f9d3d790240e/Screenshot-2023-07-11-at-13.30.23.png" />
            
            </figure><p>Once my holidays had passed, I found myself reluctantly reemerging into the world of the living. I powered on a corporate laptop, scared to check on my email inbox. However, before turning on the browser, obviously, I had to run a ping. Debugging the network is a mandatory first step after a boot, right? As expected, the network was perfectly healthy but what caught me off guard was this message:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5bipMZ0BFtWHz9fK7eNo3Q/13a2d4930b304d293727af404c798c8e/image6.png" />
            
            </figure><p>I was not expecting <b>ping</b> to <b>take countermeasures</b> that early on in a day. Gosh, I wasn't expecting any countermeasures that Monday!</p><p>Once I got over the initial confusion, I took a deep breath and collected my thoughts. You don't have to be Sherlock Holmes to figure out what has happened. I'm really fast - I started <b>ping</b> <i>before</i> the system <b>NTP</b> daemon synchronized the time. In my case, the computer clock was rolled backward, confusing ping.</p><p>While this doesn't happen too often, a computer clock can be freely adjusted either forward or backward. However, it's pretty rare for a regular network utility, like ping, to try to manage a situation like this. It's even less common to call it "taking countermeasures". I would totally expect ping to just print a nonsensical time value and move on without hesitation.</p><p>Ping developers clearly put some thought into that. I wondered how far they went. Did they handle clock changes in both directions? Are the bad measurements excluded from the final statistics? How do they test the software?</p><p>I can't just walk past ping "taking countermeasures" on me. Now I have to understand what ping did and why.</p>
    <div>
      <h3>Understanding ping</h3>
      <a href="#understanding-ping">
        
      </a>
    </div>
    <p>An investigation like this starts with a quick glance at the source code:</p>
            <pre><code> *			P I N G . C
 *
 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
 * measure round-trip-delays and packet loss across network paths.
 *
 * Author -
 *	Mike Muuss
 *	U. S. Army Ballistic Research Laboratory
 *	December, 1983</code></pre>
            <p><b>Ping</b> goes back a long way. It was originally written by <a href="https://en.wikipedia.org/wiki/Mike_Muuss">Mike Muuss</a> while at the U. S. Army Ballistic Research Laboratory, in 1983, before I was born. The code we're looking for is under <a href="https://github.com/iputils/iputils/blob/ee0a515e74b8d39fbe9b68f3309f0cb2586ccdd4/ping/ping_common.c#L746">iputils/ping/ping_common.c</a> gather_statistics() function:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2FJGGtP0ecs0zhiBKsyfxx/224080cf97fc53fa3fb83c59a86e43c9/image5.png" />
            
            </figure><p>The code is straightforward: the message in question is printed when the measured <a href="https://www.cloudflare.com/learning/cdn/glossary/round-trip-time-rtt/">RTT</a> is negative. In this case ping resets the latency measurement to zero. Here you are: "taking countermeasures" is nothing more than just marking an erroneous measurement as if it was 0ms.</p><p>But what precisely does ping measure? Is it the wall clock? The <a href="https://man7.org/linux/man-pages/man8/ping.8.html">man page</a> comes to the rescue. Ping has two modes.</p><p>The "old", -U mode, in which it uses the wall clock. This mode is less accurate (has more jitter). It calls <b>gettimeofday</b> before sending and after receiving the packet.</p><p>The "new", default, mode in which it uses "network time". It calls <b>gettimeofday</b> before sending, and gets the receive timestamp from a more accurate SO_TIMESTAMP CMSG. More on this later.</p>
    <div>
      <h3>Tracing gettimeofday is hard</h3>
      <a href="#tracing-gettimeofday-is-hard">
        
      </a>
    </div>
    <p>Let's start with a good old strace:</p>
            <pre><code>$ strace -e trace=gettimeofday,time,clock_gettime -f ping -n -c1 1.1 &gt;/dev/null
... nil ...</code></pre>
            <p>It doesn't show any calls to <b>gettimeofday</b>. What is going on?</p><p>On modern Linux some syscalls are not true syscalls. Instead of jumping to the kernel space, which is slow, they remain in userspace and go to a special code page provided by the host kernel. This code page is called <b>vdso</b>. It's visible as a <b>.so</b> library to the program:</p>
            <pre><code>$ ldd `which ping` | grep vds
    linux-vdso.so.1 (0x00007ffff47f9000)</code></pre>
            <p>Calls to the <b>vdso</b> region are not syscalls, they remain in userspace and are super fast, but classic strace can't see them. For debugging it would be nice to turn off <b>vdso</b> and fall back to classic slow syscalls. It's easier said than done.</p><p>There is no way to prevent loading of the <b>vdso</b>. However there are two ways to convince a loaded program not to use it.</p><p>The first technique is about fooling glibc into thinking the <b>vdso</b> is not loaded. This case must be handled for compatibility with ancient Linux. When bootstrapping in a freshly run process, glibc inspects the <a href="https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html">Auxiliary Vector</a> provided by ELF loader. One of the parameters has the location of the <b>vdso</b> pointer, <a href="https://man7.org/linux/man-pages/man7/vdso.7.html">the man page</a> gives this example:</p>
            <pre><code>void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR);</code></pre>
            <p>A technique proposed on <a href="https://stackoverflow.com/a/63811017">Stack Overflow</a> works like that: let's hook on a program before <b>execve</b>() exits and overwrite the Auxiliary Vector AT_SYSINFO_EHDR parameter. Here's the <a href="https://github.com/danteu/novdso/blob/master/novdso.c">novdso.c</a> code. However, the linked code doesn't quite work for me (one too many <b>kill(SIGSTOP)</b>), and has one bigger, fundamental flaw. To hook on <b>execve()</b> it uses <b>ptrace()</b> therefore doesn't work under our strace!</p>
            <pre><code>$ strace -f ./novdso ping 1.1 -c1 -n
...
[pid 69316] ptrace(PTRACE_TRACEME)  	= -1 EPERM (Operation not permitted)</code></pre>
            <p>While this technique of rewriting AT_SYSINFO_EHDR is pretty cool, it won't work for us. (I wonder if there is another way of doing that, but without ptrace. Maybe with some BPF? But that is another story.)</p><p>A second technique is to use <b>LD_PRELOAD</b> and preload a trivial library overloading the functions in question, and forcing them to go to slow real syscalls. This works fine:</p>
            <pre><code>$ cat vdso_override.c
#include &lt;sys/syscall.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;time.h&gt;
#include &lt;unistd.h&gt;

int gettimeofday(struct timeval *restrict tv, void *restrict tz) {
	return syscall(__NR_gettimeofday, (long)tv, (long)tz, 0, 0, 0, 0);
}

time_t time(time_t *tloc) {
	return syscall(__NR_time, (long)tloc, 0, 0, 0, 0, 0);
}

int clock_gettime(clockid_t clockid, struct timespec *tp) {
    return syscall(__NR_clock_gettime, (long)clockid, (long)tp, 0, 0, 0, 0);
}</code></pre>
            <p>To load it:</p>
            <pre><code>$ gcc -Wall -Wextra -fpic -shared -o vdso_override.so vdso_override.c

$ LD_PRELOAD=./vdso_override.so \
       strace -e trace=gettimeofday,clock_gettime,time \
       date

clock_gettime(CLOCK_REALTIME, {tv_sec=1688656245 ...}) = 0
Thu Jul  6 05:10:45 PM CEST 2023
+++ exited with 0 +++</code></pre>
            <p>Hurray! We can see the <b>clock_gettime</b> call in <b>strace</b> output. Surely we'll also see <b>gettimeofday</b> from our <b>ping</b>, right?</p><p>Not so fast, it still doesn't quite work:</p>
            <pre><code>$ LD_PRELOAD=./vdso_override.so \
     strace -c -e trace=gettimeofday,time,clock_gettime -f \
     ping -n -c1 1.1 &gt;/dev/null
... nil ...</code></pre>
            
    <div>
      <h3>To suid or not to suid</h3>
      <a href="#to-suid-or-not-to-suid">
        
      </a>
    </div>
    <p>I forgot that <b>ping</b> might need special permissions to read and write raw packets. Historically it had a <b>suid</b> bit set, which granted the program elevated user identity. However LD_PRELOAD doesn't work with suid. When a program is being loaded a <a href="https://github.com/bminor/musl/blob/718f363bc2067b6487900eddc9180c84e7739f80/ldso/dynlink.c#L1820">dynamic linker checks if it has <b>suid</b> bit</a>, and if so, it ignores LD_PRELOAD and LD_LIBRARY_PATH settings.</p><p>However, does <b>ping</b> need suid? Nowadays it's totally possible to send and receive ICMP Echo messages without any extra privileges, like this:</p>
            <pre><code>from socket import *
import struct

sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)
sd.connect(('1.1', 0))

sd.send(struct.pack("!BBHHH10s", 8, 0, 0, 0, 1234, b'payload'))
data = sd.recv(1024)
print('type=%d code=%d csum=0x%x id=%d seq=%d payload=%s' % struct.unpack_from("!BBHHH10s", data))</code></pre>
            <p>Now you know how to write "ping" in eight lines of Python. This Linux API is known as <b>ping socket</b>. It generally works on modern Linux, however it requires a correct sysctl, which is typically enabled:</p>
            <pre><code>$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0    2147483647</code></pre>
            <p>The <b>ping socket</b> is not as mature as UDP or TCP sockets. The "ICMP ID" field is used to dispatch an ICMP Echo Response to an appropriate socket, but when using <b>bind()</b> this property is settable by the user without any checks. A malicious user can deliberately cause an "ICMP ID" conflict.</p><p>But we're not here to discuss Linux networking API's. We're here to discuss the <b>ping</b> utility and indeed, it's using the <b>ping sockets</b>:</p>
            <pre><code>$ strace -e trace=socket -f ping 1.1 -nUc 1
socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) = 3
socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6) = 4</code></pre>
            <p>Ping sockets are rootless, and <b>ping</b>, at least on my laptop, is not a suid program:</p>
            <pre><code>$ ls -lah `which ping`
-rwxr-xr-x 1 root root 75K Feb  5  2022 /usr/bin/ping</code></pre>
            <p>So why doesn't the LD_PRELOAD? It turns out <b>ping</b> binary holds a CAP_NET_RAW capability. Similarly to suid, this is preventing the library preloading machinery from working:</p>
            <pre><code>$ getcap `which ping`
/usr/bin/ping cap_net_raw=ep</code></pre>
            <p>I think this capability is enabled only to handle the case of a misconfigured <b>net.ipv4.ping_group_range</b> sysctl. For me ping works perfectly fine without this capability.</p>
    <div>
      <h3>Rootless is perfectly fine</h3>
      <a href="#rootless-is-perfectly-fine">
        
      </a>
    </div>
    <p>Let's remove the CAP_NET_RAW and try out LD_PRELOAD hack again:</p>
            <pre><code>$ cp `which ping` .

$ LD_PRELOAD=./vdso_override.so strace -f ./ping -n -c1 1.1
...
setsockopt(3, SOL_SOCKET, SO_TIMESTAMP_OLD, [1], 4) = 0
gettimeofday({tv_sec= ... ) = 0
sendto(3, ...)
setitimer(ITIMER_REAL, {it_value={tv_sec=10}}, NULL) = 0
recvmsg(3, { ... cmsg_level=SOL_SOCKET, 
                 cmsg_type=SO_TIMESTAMP_OLD, 
                 cmsg_data={tv_sec=...}}, )</code></pre>
            <p>We finally made it! Without -U, in the "network timestamp" mode, <b>ping</b>:</p><ul><li><p>Sets SO_TIMESTAMP flag on a socket.</p></li><li><p>Calls <b>gettimeofday</b> before sending the packet.</p></li><li><p>When fetching a packet, gets the timestamp from the <b>CMSG</b>.</p></li></ul>
    <div>
      <h3>Fault injection - fooling ping</h3>
      <a href="#fault-injection-fooling-ping">
        
      </a>
    </div>
    <p>With <b>strace</b> up and running we can finally do something interesting. You see, <b>strace</b> has a little known fault injection feature, named <a href="https://man7.org/linux/man-pages/man1/strace.1.html">"tampering" in the manual</a>:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6EpzqSkXe9BCttqJajgXpi/79d3f4051066ab7e8fa88795c2c33e58/image3.png" />
            
            </figure><p>With a couple of command line parameters we can overwrite the result of the <b>gettimeofday</b> call. I want to set it forward to confuse ping into thinking the SO_TIMESTAMP time is in the past:</p>
            <pre><code>LD_PRELOAD=./vdso_override.so \
    strace -o /dev/null -e trace=gettimeofday \
            -e inject=gettimeofday:poke_exit=@arg1=ff:when=1 -f \
    ./ping -c 1 -n 1.1.1.1

PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
./ping: Warning: time of day goes back (-59995290us), taking countermeasures
./ping: Warning: time of day goes back (-59995104us), taking countermeasures
64 bytes from 1.1.1.1: icmp_seq=1 ttl=60 time=0.000 ms

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.000/0.000/0.000/0.000 ms</code></pre>
            <p>It worked! We can now generate the "taking countermeasures" message reliably!</p><p>While we can cheat on the <b>gettimeofday</b> result, with <b>strace</b> it's impossible to overwrite the CMSG timestamp. Perhaps it might be possible to adjust the CMSG timestamp with Linux <a href="https://man7.org/linux/man-pages/man7/time_namespaces.7.html">time namespaces</a>, but I don't think it'll work. As far as I understand, time namespaces are not taken into account by the network stack. A program using SO_TIMESTAMP is deemed to compare it against the system clock, which might be rolled backwards.</p>
    <div>
      <h3>Fool me once, fool me twice</h3>
      <a href="#fool-me-once-fool-me-twice">
        
      </a>
    </div>
    <p>At this point we could conclude our investigation. We're now able to reliably trigger the "taking countermeasures" message using strace fault injection.</p><p>There is one more thing though. When sending ICMP Echo Request messages, does <b>ping</b> <b>remember</b> the send timestamp in some kind of hash table? That might be wasteful considering a long-running ping sending thousands of packets.</p><p>Ping is smart, and instead puts the timestamp in the ICMP Echo Request <b>packet payload</b>!</p><p>Here's how the full algorithm works:</p><ol><li><p>Ping sets the SO_TIMESTAMP_OLD socket option to receive timestamps.</p></li><li><p>It looks at the wall clock with <b>gettimeofday</b>.</p></li><li><p>It puts the current timestamp in the first bytes of the ICMP payload.</p></li><li><p>After receiving the ICMP Echo Reply packet, it inspects the two timestamps: the send timestamp from the payload and the receive timestamp from CMSG.</p></li><li><p>It calculates the RTT delta.</p></li></ol><p>This is pretty neat! With this algorithm, ping doesn't need to remember much, and can have an unlimited number of packets in flight! (For completeness, ping maintains a small fixed-size bitmap to account for the DUP! packets).</p><p>What if we set a packet length to be less than 16 bytes? Let's see:</p>
            <pre><code>$ ping 1.1 -c2 -s0
PING 1.1 (1.0.0.1) 0(28) bytes of data.
8 bytes from 1.0.0.1: icmp_seq=1 ttl=60
8 bytes from 1.0.0.1: icmp_seq=2 ttl=60
--- 1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms</code></pre>
            <p>In such a case ping just skips the RTT from the output. Smart!</p><p>Right... this opens two completely new subjects. While ping was written back when everyone was friendly, today’s Internet can have rogue actors. What if we spoofed responses to confuse ping. Can we: cut the payload to prevent ping from producing RTT, and spoof the timestamp and fool the RTT measurements?</p><p>Both things work! The truncated case will look like this to the sender:</p>
            <pre><code>$ ping 139.162.188.91
PING 139.162.188.91 (139.162.188.91) 56(84) bytes of data.
8 bytes from 139.162.188.91: icmp_seq=1 ttl=53 (truncated)</code></pre>
            <p>The second case, of an overwritten timestamp, is even cooler. We can move timestamp forwards causing ping to show our favorite "taking countermeasures" message:</p>
            <pre><code>$ ping 139.162.188.91  -c 2 -n
PING 139.162.188.91 (139.162.188.91) 56(84) bytes of data.
./ping: Warning: time of day goes back (-1677721599919015us), taking countermeasures
./ping: Warning: time of day goes back (-1677721599918907us), taking countermeasures
64 bytes from 139.162.188.91: icmp_seq=1 ttl=53 time=0.000 ms
./ping: Warning: time of day goes back (-1677721599905149us), taking countermeasures
64 bytes from 139.162.188.91: icmp_seq=2 ttl=53 time=0.000 ms

--- 139.162.188.91 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.000/0.000/0.000/0.000 ms</code></pre>
            <p>Alternatively we can move the time in the packet backwards causing <a href="https://github.com/iputils/iputils/issues/480">ping to show nonsensical RTT values</a>:</p>
            <pre><code>$ ./ping 139.162.188.91  -c 2 -n
PING 139.162.188.91 (139.162.188.91) 56(84) bytes of data.
64 bytes from 139.162.188.91: icmp_seq=1 ttl=53 time=1677721600430 ms
64 bytes from 139.162.188.91: icmp_seq=2 ttl=53 time=1677721600084 ms

--- 139.162.188.91 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 1677721600084.349/1677721600257.351/1677721600430.354/-9223372036854775.-808 ms</code></pre>
            <p>We proved that "countermeasures" work only when time moves in one direction. In another direction ping is just fooled.</p><p>Here's a rough scapy snippet that generates an ICMP Echo Response fooling ping:</p>
            <pre><code># iptables -I INPUT -i eth0 -p icmp --icmp-type=8 -j DROP
import scapy.all as scapy
import struct

def custom_action(echo_req):
    try:
    	payload = bytes(echo_req[scapy.ICMP].payload)
    	if len(payload) &gt;= 8:
        	ts, tu = struct.unpack_from("&lt;II", payload)
        	payload = struct.pack("&lt;II", (ts-0x64000000)&amp;0xffffffff, tu) \
                     + payload[8:]

    	echo_reply = scapy.IP(
        	dst=echo_req[scapy.IP].src,
        	src=echo_req[scapy.IP].dst,
    	) / scapy.ICMP(type=0, code=0,
                 	id=echo_req[scapy.ICMP].id,
                 	seq=echo_req.payload.seq,
   	  	) / payload
    	scapy.send(echo_reply,iface=iface)
    except Exception as e:
        pass

scapy.sniff(filter="icmp and icmp[0] = 8", iface=iface, prn=custom_action)</code></pre>
            
    <div>
      <h3>Leap second</h3>
      <a href="#leap-second">
        
      </a>
    </div>
    <p>In practice, how often does time change on a computer? The <b>NTP</b> daemon adjusts the clock all the time to account for any drift. However, these are very small changes. Apart from initial clock synchronization after boot or sleep wakeup, big clock shifts shouldn't really happen.</p><p>There are exceptions as usual. Systems that operate in virtual environments or have unreliable Internet connections often experience their clocks getting out of sync.</p><p>One notable case that affects all computers is a coordinated clock adjustment called a <a href="https://en.wikipedia.org/wiki/Leap_second">leap second</a>. It causes the clock to move backwards, which is particularly troublesome. An issue with handling leap second <a href="/how-and-why-the-leap-second-affected-cloudflare-dns/">caused our engineers a headache in late 2016</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4iGPlBeYYXm0RYyxhEmOMQ/20b49ba0ad47eeb0404610e710bd4226/Screenshot-2023-07-11-at-13.33.02.png" />
            
            </figure><p>Leap seconds often cause issues, so the current consensus is to <a href="https://www.nytimes.com/2022/11/19/science/time-leap-second-bipm.html">deprecate them by 2035</a>. However, <a href="https://en.wikipedia.org/wiki/Leap_second#International_proposals_for_elimination_of_leap_seconds">according to Wikipedia</a> the solution seem to be to just kick the can down the road:</p><blockquote><p><i>A suggested possible future measure would be to let the discrepancy increase to a full minute, which would take 50 to 100 years, and then have the last minute of the day taking two minutes in a "kind of smear" with no discontinuity.</i></p></blockquote><p>In any case, there hasn't been a leap second since 2016, there might be some in the future, but there likely won't be any after 2035. Many environments already use a <a href="https://cloudplatform.googleblog.com/2015/05/Got-a-second-A-leap-second-that-is-Be-ready-for-June-30th.html">leap second smear</a> to avoid the problem of clock jumping back.</p><p>In most cases, it might be completely fine to ignore the clock changes. When possible, to count time durations use CLOCK_MONOTONIC, which is bulletproof.</p><p>We haven't mentioned <a href="https://en.wikipedia.org/wiki/Daylight_saving_time">daylight savings</a> clock adjustments here because, from a computer perspective they are not real clock changes! Most often programmers deal with the operating system clock, which is typically set to the <a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC timezone</a>. DST timezone is taken into account only when pretty printing the date on screen. The underlying software operates on integer values. Let's consider an example of two timestamps, which in my <a href="https://devblogs.microsoft.com/oldnewthing/20061027-00/?p=29213">Warsaw timezone</a>, appear as two different DST timezones. While it may like the clock rolled back, this is just a user interface illusion. The integer timestamps are sequential:</p>
            <pre><code>$ date --date=@$[1698541199+0]
Sun Oct 29 02:59:59 AM CEST 2023

$ date --date=@$[1698541199+1]
Sun Oct 29 02:00:00 AM CET 2023</code></pre>
            
    <div>
      <h3>Lessons</h3>
      <a href="#lessons">
        
      </a>
    </div>
    <p>Arguably, the clock jumping backwards is a rare occurrence. It's very hard to test for such cases, and I was surprised to find that <b>ping</b> made such an attempt. To avoid the problem, to measure the latency ping might use CLOCK_MONOTONIC, its developers already <a href="https://github.com/iputils/iputils/commit/4fd276cd8211c502cb87c5db0ce15cd685177216">use this time source in another place</a>.</p><p>Unfortunately this won't quite work here. Ping needs to compare send timestamp to receive timestamp from SO_TIMESTAMP CMSG, which uses the non-monotonic system clock. Linux API's are sometimes limited, and dealing with time is hard. For time being, clock adjustments will continue to confuse ping.</p><p>In any case, now we know what to do when <b>ping</b> is "<b>taking countermeasures</b>"! Pull down your periscope and check the <b>NTP</b> daemon status!</p> ]]></content:encoded>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">6M6gXK7v29wVHnBMZMYRpS</guid>
            <dc:creator>Marek Majkowski</dc:creator>
        </item>
        <item>
            <title><![CDATA[How Orpheus automatically routes around bad Internet weather]]></title>
            <link>https://blog.cloudflare.com/orpheus-saves-internet-requests-while-maintaining-speed/</link>
            <pubDate>Mon, 19 Jun 2023 13:00:49 GMT</pubDate>
            <description><![CDATA[ Cloudflare’s mission is to help build a better Internet for everyone, and Orpheus plays an important role in realizing this mission everyday. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Cloudflare’s mission is to help build a better Internet for everyone, and <a href="/orpheus/">Orpheus</a> plays an important role in realizing this mission. Orpheus identifies Internet connectivity outages beyond Cloudflare’s network in real time then leverages the scale and speed of Cloudflare’s network to find alternative paths around those outages. This ensures that everyone can reach a Cloudflare customer’s <a href="https://www.cloudflare.com/learning/cdn/glossary/origin-server/">origin server</a> no matter what is happening on the Internet. The end result is powerful: Cloudflare  protects customers from Internet incidents outside our network while maintaining the average latency and speed of our customer’s traffic.</p><p>A little less than two years ago, Cloudflare made <a href="/orpheus/">Orpheus automatically available to all customers for free</a>. Since then, Orpheus has saved 132 billion Internet requests from failing by intelligently routing them around connectivity outages, prevented 50+ Internet incidents from impacting our customers, and made our customer’s origins more reachable to everyone on the Internet. Let’s dive into how Orpheus accomplished these feats over the last year.</p>
    <div>
      <h3>Increasing origin reachability</h3>
      <a href="#increasing-origin-reachability">
        
      </a>
    </div>
    <p>One service that Cloudflare offers is a <a href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/">reverse proxy</a> that receives Internet requests from end users then applies any number of services like <a href="https://www.cloudflare.com/learning/ddos/what-is-a-ddos-attack/">DDoS protection</a>, <a href="https://www.cloudflare.com/learning/cdn/what-is-caching/">caching</a>, <a href="https://www.cloudflare.com/learning/performance/what-is-load-balancing/">load balancing</a>, and / or <a href="https://www.cloudflare.com/learning/ssl/what-is-encryption/">encryption</a>. If the response to an end user’s request isn’t cached, Cloudflare routes the request to our customer’s origin servers. To be successful, end users need to be able to connect to Cloudflare, and Cloudflare needs to connect to our customer’s origin servers. With end users and customer origins around the world, and ~20% of websites using our network, this task is a tall order!</p><p>Orpheus provides origin reachability benefits to everyone using Cloudflare by identifying invalid paths on the Internet in real time, then routing traffic via alternative paths that are working as expected. This ensures Cloudflare can reach an origin no matter what problems are happening on the Internet on any given day.</p>
    <div>
      <h3>Reducing 522 errors</h3>
      <a href="#reducing-522-errors">
        
      </a>
    </div>
    <p>At some point while browsing the Internet, you may have run into this <a href="https://support.cloudflare.com/hc/en-us/articles/115003011431-Troubleshooting-Cloudflare-5XX-errors#522error">522 error</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1uOmXFuEIqQuOncFseJNVk/2e9ae2ba47e57ce4bd6b748556d19956/image3-4.png" />
            
            </figure><p>This error indicates that you, the end user, was unable to access content on a Cloudflare customer’s origin server because Cloudflare couldn’t connect to the origin. Sometimes, this error occurs because the origin is offline for everyone, and ultimately the origin owner needs to fix the problem. Other times, this error can occur even when the origin server is up and able to receive traffic. In this case, some people can reach content on the origin server, but other people using a different Internet routing path cannot because of connectivity issues across the Internet.</p><p>Some days, a specific network may have excellent connectivity, while other days that network may be congested or have paths that are impassable altogether. The Internet is a massive and unpredictable <a href="https://www.cloudflare.com/learning/network-layer/how-does-the-internet-work/">network of networks</a>, and the “weather” of the Internet changes every day.</p><p>When you see this error, Cloudflare attempted to connect to an origin on behalf of the end user, but did not receive a response back from the origin. Either the connection request never reached the origin, or the origin’s reply was dropped on the way back to Cloudflare. In the case of 522 errors, Cloudflare and the origin server could both be working as expected, but packets are dropped on the network path between them.</p><p>These 522 errors can cause a lot of frustration, and Orpheus was built to reduce them. The goal of Orpheus is to ensure that if at least one Cloudflare data center can connect to an origin, then anyone using Cloudflare’s network can also reach that origin, even if there are Internet connectivity problems happening outside of Cloudflare’s network.</p>
    <div>
      <h3>Improving origin reachability for an example customer using Cloudflare</h3>
      <a href="#improving-origin-reachability-for-an-example-customer-using-cloudflare">
        
      </a>
    </div>
    <p>Let’s look at a concrete example of how Orpheus makes the Internet <a href="https://blog.cloudflare.com/50-years-of-the-internet-work-in-progress-to-a-better-internet/">better</a> for everyone by saving an origin request that would have otherwise failed. Imagine that you’re running an <a href="https://www.cloudflare.com/ecommerce/">e-commerce website</a> that sells dog toys online, and your store is hosted by an origin server in Chicago.</p><p>Imagine there are two different customers visiting your website at the same time: the first customer lives in Seattle, and the second customer lives in Tampa. The customer in Seattle reaches your origin just fine, but the customer in Tampa tries to connect to your origin and experiences a problem. It turns out that a construction crew accidentally damaged an Internet fiber line in Tampa, and Tampa is having connectivity issues with Chicago. As a result, any customer in Tampa receives a 522 error when they try to buy your dog toys online.</p><p>This is where Orpheus comes in to save the day. Orpheus detects that users in Tampa are receiving 522 errors when connecting to Chicago. Its database shows there is another route from Tampa through Boston and then to Chicago that is valid. As a result, Orpheus saves the end user’s request by rerouting it through Boston and taking an alternative path. Now, everyone in Tampa can still buy dog toys from your website hosted in Chicago, even though a fiber line was damaged unexpectedly.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/44iuCk9vxool3B7x7YJnXa/10a905865a76e4e8ce207de1d18c8f6b/image1-7.png" />
            
            </figure>
    <div>
      <h3>How does Orpheus save requests that would otherwise fail via only BGP?</h3>
      <a href="#how-does-orpheus-save-requests-that-would-otherwise-fail-via-only-bgp">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/">BGP (Border Gateway Protocol)</a> is like the postal service of the Internet. It’s the protocol that makes the Internet work by enabling data routing. When someone requests data over the Internet, BGP is responsible for looking at all the available paths a request could take, then selecting a route.</p><p>BGP is designed to route around network failures by finding alternative paths to the destination IP address after the preferred path goes down. Sometimes, BGP does not route around a network failure at all. In this case, Cloudflare still receives BGP advertisements that an origin network is reachable via a particular <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/">autonomous system (AS)</a>, when actually packets sent through that AS will be dropped. In contrast, Orpheus will test alternate paths via synthetic probes and with real time traffic to ensure it is always using valid routes. Even when working as designed, BGP takes time to converge after a network disruption; Orpheus can react faster, find alternative paths to the origin that route around temporary or persistent errors, and ultimately save more Internet requests.</p><p>Additionally, BGP routes can be vulnerable to <a href="https://www.cloudflare.com/learning/security/glossary/bgp-hijacking/">hijacking</a>. If a BGP route is hijacked, Orpheus can prevent Internet requests from being dropped by invalid BGP routes by frequently testing all routes and examining the results to ensure they’re working as expected. In any of these cases, Orpheus routes around these BGP issues by taking advantage of the scale of Cloudflare’s global network which directly connects to <a href="/cloudflare-connected-in-over-300-cities/">12,000 networks, features data centers across 300 cities, and has 197 Tbps of network capacity</a></p><p>Let’s give an example of how Orpheus can save requests that would otherwise fail if only using BGP. Imagine an end user in Mumbai sends a request to a Cloudflare customer with an origin server in New York. For any request that misses <a href="https://www.cloudflare.com/learning/cdn/what-is-caching/">Cloudflare’s cache</a>, Cloudflare forwards the request from Mumbai to the website’s origin server in New York. Now imagine something happens, and the origin is no longer reachable from India: maybe <a href="/aae-1-smw5-cable-cuts/">a fiber optic cable was cut in Egypt</a>, <a href="/how-verizon-and-a-bgp-optimizer-knocked-large-parts-of-the-internet-offline-today/">a different network advertised a BGP route it shouldn’t have</a>, or an intermediary AS between Cloudflare and the origin was misconfigured that day.</p><p>In any of these scenarios, Orpheus can leverage the scale of Cloudflare’s global network to reach the origin in New York via an alternate path. While the direct path from Mumbai to New York may be unreachable, an alternate path from Mumbai, through London, then to New York may be available. This alternate path is valid because it uses different physical Internet connections that are unaffected by the issues with directly connecting from Mumbai to New York. In this case, Orpheus selects the alternate route through London and saves a request that would otherwise fail via the direct connection.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2g4XlGEt326h2LwNuFT5zN/68a0a5fac28b270e7ecc0a284351a4f1/image4-5.png" />
            
            </figure>
    <div>
      <h3>How Orpheus was built by reusing components of Argo Smart Routing</h3>
      <a href="#how-orpheus-was-built-by-reusing-components-of-argo-smart-routing">
        
      </a>
    </div>
    <p>Back in 2017, Cloudflare released <a href="/argo/">Argo Smart Routing</a> which decreases latency by an average of 30%, improves security, and increases reliability. To help Cloudflare achieve its goal of helping build a better Internet for everyone, we decided to take the features that offered “increased reliability” in Argo Smart Routing and make them available to every Cloudflare user for free with <a href="/orpheus/">Orpheus</a>.</p><p>Argo Smart Routing’s architecture has two primary components: <a href="https://www.cloudflare.com/learning/network-layer/what-is-the-control-plane/">the data plane and the control plane</a>. The control plane is responsible for computing the fastest routes between two locations and identifying potential failover paths in case the fastest route is down. The data plane is responsible for sending requests via the routes defined by the control plane, or detecting in real-time when a route is down and sending a request via a failover path as needed.</p><p>Orpheus was born with a simple technical idea: Cloudflare could deploy an alternate version of Argo’s control plane where the routing table only includes failover paths. Today, this alternate control plane makes up the core of Orpheus. If a request that travels through Cloudflare’s network is unable to connect to the origin via a preferred path, then Orpheus’s data plane selects a failover path from the routing table in its control plane. Orpheus prioritizes using failover paths that are more reliable to increase the likelihood a request uses the failover route and is successful.</p><p>Orpeus also takes advantage of a complex Internet monitoring system that we had already built for Argo Smart Routing. This system is constantly testing the health of many internet routing paths between different Cloudflare data centers and a customer’s origin by periodically opening then closing a TCP connection. This is called a synthetic probe, and the results are used for Argo Smart Routing, Orpheus, and even in other Cloudflare products. Cloudflare directly connects to <a href="https://www.cloudflare.com/network/">11,000 networks</a>, and typically there are many different Internet routing paths that reach the same origin. Argo and Orpheus maintain a database of the results of all TCP connections that opened successfully or failed with their corresponding routing paths.</p>
    <div>
      <h3>Scaling the Orpheus data plane to save requests for everyone</h3>
      <a href="#scaling-the-orpheus-data-plane-to-save-requests-for-everyone">
        
      </a>
    </div>
    <p>Cloudflare proxies millions of requests to customers' origins every second, and we had to make some improvements to Orpheus before it was ready to save users’ requests at scale. In particular, Cloudflare designed Orpheus to only process and reroute requests that would otherwise fail. In order to identify these requests, we added an error cache to <a href="https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/">Cloudflare’s layer 7 HTTP</a> stack.</p><p>When you send an Internet request (TCP SYN) through Cloudflare to our customer’s origin, and Cloudflare doesn’t receive a response (TCP SYN/ACK), the end user receives a 522 error (<a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure">learn more about TCP flags</a>). Orpheus creates an entry in the error cache for each unique combination of a 522 error, origin address, and a specific route to that origin. The next time a request is sent to the same origin address via the same route, Orpheus will check the error cache for relevant entries. If there is a hit in the error cache, then Orpheus’s data plane will select an alternative route to prevent subsequent requests from failing.</p><p>To keep entries in the error cache updated, Orpheus will use live traffic to retry routes that previously failed to check their status. Routes in the error cache are periodically retried with a bounded <a href="https://en.wikipedia.org/wiki/Exponential_backoff">exponential backoff</a>. Unavailable routes are tested every 5th, 25th, 125th, 625th, and 3,125th request (the maximum bound). If the test request that’s sent down the original path fails, Orpheus saves the test request, sends it via the established alternate path, and updates the backoff counter. If a test request is successful, then the failed route is removed from the error cache, and normal routing operations are restored. Additionally, the error cache has an expiry period of 10 minutes. This prevents the cache from storing entries on failed routes that rarely receive additional requests.</p><p>The error cache has notable a trade-off; one direct-to-origin request must fail before Orpheus engages and saves subsequent requests. Clearly this isn’t ideal, and the Argo / Orpheus engineering team is hard at work improving Orpheus so it can prevent any request from failing.</p>
    <div>
      <h3>Making Orpheus faster and more responsive</h3>
      <a href="#making-orpheus-faster-and-more-responsive">
        
      </a>
    </div>
    <p>Orpheus does a great job of identifying congested or unreachable paths on the Internet, and re-routing requests that would have otherwise failed. However, there is always room for improvement, and Cloudflare has been hard at work to make Orpheus even better.</p><p>Since its release, Orpheus was built to select failover paths with the highest predicted reliability when it saves a request to an origin. This was an excellent first step, but sometimes a request that was re-routed by Orpheus would take an inefficient path that had better origin reachability but also increased latency. With recent improvements, the Orpheus routing algorithm balances both latency and origin reachability when selecting a new route for a request. If an end user makes a request to an origin, and that request is re-routed by Orpheus, it’s nearly as fast as any other request on Cloudflare’s network.</p><p>In addition to decreasing the latency of Orpheus requests, we’re working to make Orpheus more responsive to connectivity changes across the Internet. Today, Orpheus leverages synthetic probes to test whether Internet routes are reachable or unreachable. In the near future, Orpheus will also leverage real-time traffic data to more quickly identify Internet routes that are unreachable and reachable. This will enable Orpheus to re-route traffic around connectivity problems on the Internet within minutes rather than hours.</p>
    <div>
      <h3>Expanding Orpheus to save WebSockets requests</h3>
      <a href="#expanding-orpheus-to-save-websockets-requests">
        
      </a>
    </div>
    <p>Previously, Orpheus focused on saving HTTP and TCP Internet requests. Cloudflare has seen amazing benefits to origin reliability and Internet stability for these types of requests, and we’ve been hard at work to expand Orpheus to also save WebSocket requests from failing.</p><p>WebSockets is a common Internet protocol that prioritizes sending real time data between a client and server by maintaining an open connection between that client and server. Imagine that you (the client) have sent a request to see a website’s home page (which is generated by the server). When using HTTP, the connection between the client and server is established by the client, and the connection is closed once the request is completed. That means that if you send three requests to a website, three different connections are opened and closed for each request.</p><p>In contrast, when using the WebSockets protocol, one connection is established between the client and server. All requests moving in between the client and server are sent through this connection until the connection is terminated. In this case, you could send 10 requests to a website, and all of those requests would travel over the same connection. Due to these differences in protocol, Cloudflare had to adjust to Orpheus to make it capable of also saving WebSockets requests. Now all Cloudflare customers that use WebSockets in their Internet applications can expect the same level of stability and resiliency across their HTTP, TCP, and WebSockets traffic.</p><p>P.S. If you’re interested in working on Orpheus, <a href="https://www.cloudflare.com/careers/">drop us a line</a>!</p>
    <div>
      <h3>Orpheus and Argo Smart Routing</h3>
      <a href="#orpheus-and-argo-smart-routing">
        
      </a>
    </div>
    <p>Orpheus runs on the same technology that powers Cloudflare’s <a href="https://www.cloudflare.com/products/argo-smart-routing/">Argo Smart Routing</a> product. While Orpheus is designed to maximize origin reachability, Argo Smart Routing leverages network latency data to accelerate traffic on Cloudflare’s network and find the fastest route between an end user and a customer’s origin. On average, customers using Argo Smart Routing see that their <a href="https://www.cloudflare.com/pg-lp/argo-smart-routing/">web assets perform 30% faster</a>. Together, Orpheus and Argo Smart Routing work to improve the end user experience for websites and contribute to Cloudflare’s goal of helping build a better Internet.</p><p>If you’re a Cloudflare customer, you are automatically using Orpheus behind the scenes and improving your website’s availability. If you want to make the web faster for your users, you can log in to the Cloudflare dashboard and add Argo Smart Routing to your contract or plan today.</p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">1FLCXPnp4ARlDbSb7VNQPp</guid>
            <dc:creator>Chris Draper</dc:creator>
            <dc:creator>Braden Ehrat</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare's global network grows to 300 cities and ever closer to end users with connections to 12,000 networks]]></title>
            <link>https://blog.cloudflare.com/cloudflare-connected-in-over-300-cities/</link>
            <pubDate>Mon, 19 Jun 2023 13:00:16 GMT</pubDate>
            <description><![CDATA[ We are pleased to announce that Cloudflare is now connected to over 12,000 Internet networks in over 300 cities around the world ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4PkXmBAp3jn8r0gnWqIEAx/15007c52bdd3178d13352edb92914e97/12-000-networks-1.png" />
            
            </figure><p>We make no secret about how passionate we are about building a world-class global <a href="https://www.cloudflare.com/network/">network</a> to deliver the best possible experience for our customers. This means an unwavering and continual dedication to always improving the breadth (number of cities) and depth (number of interconnects) of our network.</p><p><b>This is why we are pleased to announce that Cloudflare is now connected to over 12,000 Internet networks in over 300 cities around the world!</b></p><p>The Cloudflare global network runs every service in every data center so your users have a consistent experience everywhere—whether you are in <a href="/reykjavik-cloudflares-northernmost-location/">Reykjavík</a>, <a href="/cloudflare-deployment-in-guam/">Guam</a> or in the vicinity of any of the 300 cities where Cloudflare lives. This means all customer traffic is processed at the data center closest to its source, with no backhauling or performance tradeoffs.</p><p>Having Cloudflare’s network present in hundreds of cities globally is critical to providing new and more convenient ways to serve our customers and their customers. However, the breadth of our infrastructure network provides other critical purposes. Let’s take a closer look at the reasons we build and the real world impact we’ve seen to customer experience:</p>
    <div>
      <h3>Reduce latency</h3>
      <a href="#reduce-latency">
        
      </a>
    </div>
    <p>Our network allows us to sit approximately 50 ms from 95% of the Internet-connected population globally. Nevertheless, we are constantly reviewing network performance metrics and working with local regional Internet service providers to ensure we focus on growing underserved markets where we can add value and improve performance. So far, in 2023 we’ve already added 12 new cities to bring our network to over 300 cities spanning 122 unique countries!</p>
<table>
<thead>
  <tr>
    <th><span>City</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Albuquerque, New Mexico, US</span></td>
  </tr>
  <tr>
    <td><span>Austin, Texas, US</span></td>
  </tr>
  <tr>
    <td><span>Bangor, Maine, US</span></td>
  </tr>
  <tr>
    <td><span>Campos dos Goytacazes, Brazil</span></td>
  </tr>
  <tr>
    <td><span>Fukuoka, Japan</span></td>
  </tr>
  <tr>
    <td><span>Kingston, Jamaica</span></td>
  </tr>
  <tr>
    <td><span>Kinshasa, Democratic Republic of the Congo</span></td>
  </tr>
  <tr>
    <td><span>Lyon, France</span></td>
  </tr>
  <tr>
    <td><span>Oran, Algeria</span></td>
  </tr>
  <tr>
    <td><span>São José dos Campos, Brazil</span></td>
  </tr>
  <tr>
    <td><span>Stuttgart, Germany</span></td>
  </tr>
  <tr>
    <td><span>Vitoria, Brazil</span></td>
  </tr>
</tbody>
</table><p>In May, we activated a new data center in Campos dos Goytacazes, Brazil, where we interconnected with a regional network provider, serving 100+ local ISPs. While it's not too far from Rio de Janeiro (270km) it still cut our 50th and 75th percentile latency measured from the TCP handshake between Cloudflare's servers and the user's device in half and provided a noticeable performance improvement!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1CETPT4paJnZPdfob5xoWw/868652ca9f3643e7d1affa1f908b758d/image1-8.png" />
            
            </figure>
    <div>
      <h3>Improve interconnections</h3>
      <a href="#improve-interconnections">
        
      </a>
    </div>
    <p>A larger number of local interconnections facilitates direct connections between network providers, <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">content delivery networks</a>, and regional Internet Service Providers. These interconnections enable faster and more efficient data exchange, content delivery, and collaboration between networks.</p><p>Currently there are approximately 74,000<sup>1</sup> AS numbers routed globally. An <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/">Autonomous System</a> (AS) number is a unique number allocated per ISP, enterprise, cloud, or similar network that maintains Internet routing capabilities using BGP. Of these approximate 74,000 ASNs, 43,000<sup>2</sup> of them are stub ASNs, or only connected to one other network. These are often enterprise, or internal use ASNs, that only connect to their own ISP or internal network, but not with other networks.</p><p>It’s mind blowing to consider that Cloudflare is directly connected to 12,372 unique Internet networks, or approximately 1/3rd of the possible networks to connect globally! This direct connectivity builds resilience and enables performance, making sure there are multiple places to connect between networks, ISPs, and enterprises, but also making sure those connections are as fast as possible.</p><p>A previous example of this was shown as we started connecting more locally. As seen in this <a href="/30-more-traffic-in-less-than-a-blink-of-an-ey/">blog post</a> the local connections even increased how much our network was being used: better performance drives further usage!</p><p>At Cloudflare we ensure that infrastructure expansion strategically aligns to building in markets where we can interconnect deeper, because increasing our network breadth is only as valuable as the number of local interconnections that it enables. For example, we recently connected to a local ISP (representing a new ASN connection) in Pakistan, where the 50th percentile improved from ~90ms to 5ms!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6LklYvBqVmhxoxrOmREPqr/047aa3b950c377ea6894dde7b9fa4cc3/image2-7.png" />
            
            </figure>
    <div>
      <h3>Build resilience</h3>
      <a href="#build-resilience">
        
      </a>
    </div>
    <p>Network expansion may be driven by reducing latency and improving interconnections, but it’s equally valuable to our existing network infrastructure. Increasing our geographic reach strengthens our redundancy, localizes failover and helps further distribute compute workload resulting in more effective capacity management. This improved resilience reduces the risk of service disruptions and ensures network availability even in the event of hardware failures, natural disasters, or other unforeseen circumstances. It enhances reliability and prevents single points of failure in the network architecture.</p><p>Ultimately, our commitment to strategically expanding the breadth and depth of our network delivers improved latency, stronger interconnections and a more resilient architecture - all critical components of a better Internet! If you’re a network operator, and are interested in how, together, we can deliver an improved user experience, we’re here to help! Please check out our <a href="https://www.cloudflare.com/partners/peering-portal/">Edge Partner Program</a> and let’s get connected.</p><p>........</p><p><sup>1</sup><a href="https://www.cidr-report.org/as2.0/">CIDR Report</a></p><p><sup>2</sup><a href="https://bgp.potaroo.net/cgi-bin/plota?file=%2fvar%2fdata%2fbgp%2frva%2dmrt%2f6447%2fbgp%2das%2done%2etxt&amp;descr=Origin%20ASs%20announced%20via%20a%20single%20AS%20path&amp;ylabel=Origin%20ASs%20announced%20via%20a%20single%20AS%20path&amp;with=step">Origin ASs announced via a single AS path</a></p> ]]></content:encoded>
            <category><![CDATA[Speed Week]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Network Interconnect]]></category>
            <guid isPermaLink="false">1NlDmm0M6PYgsQlYzkeBLz</guid>
            <dc:creator>Damian Matacz</dc:creator>
            <dc:creator>Marcelo Affonso</dc:creator>
            <dc:creator>Tom Paseka</dc:creator>
            <dc:creator>Joanne Liew</dc:creator>
        </item>
        <item>
            <title><![CDATA[The European Network Usage Fees proposal is about much more than a fight between Big Tech and Big European telcos]]></title>
            <link>https://blog.cloudflare.com/eu-network-usage-fees/</link>
            <pubDate>Mon, 08 May 2023 16:31:50 GMT</pubDate>
            <description><![CDATA[ There’s an important debate happening in Europe that could affect the future of the Internet. The European Commission is considering new rules for how networks connect to each other on the Internet. ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4y22iFSEioQj0S4JrypqFb/8b56c96421d0839ec419aeb14dc1baff/1-1.png" />
            
            </figure><p>There’s an important debate happening in Europe that could affect the future of the Internet. The European Commission is considering new rules for how networks connect to each other on the Internet. It’s considering proposals that – no hyperbole – will slow the Internet for consumers and are dangerous for the Internet.</p><p>The large incumbent telcos are complaining loudly to anyone who wants to listen that they aren’t being adequately compensated for the capital investments they’re making. These telcos are a set of previously regulated monopolies who still constitute the largest telcos by revenue in Europe in today's competitive market. They say traffic volumes, largely due to <a href="https://www.cloudflare.com/developer-platform/solutions/live-streaming/">video streaming</a>, are growing rapidly, implying they need to make capital investments to keep up. And they <a href="https://etno.eu/news/all-news/760:q-a-23.html">call</a> for new charges on big US tech companies: a “fair share” contribution that those networks should make to European Internet infrastructure investment.</p><p>In response to this campaign, in February the European Commission <a href="https://ec.europa.eu/commission/presscorner/detail/en/IP_23_985">released</a> a set of recommended actions and proposals “aimed to make Gigabit connectivity available to all citizens and businesses across the EU by 2030.” The Commission goes on to <a href="https://ec.europa.eu/eusurvey/runner/Future_of_Connectivity#">say</a> that “Reliable, fast and secure connectivity is a must for everybody and everywhere in the Union, including in rural and remote areas.” While this goal is certainly the right one, our agreement with the European Commission’s approach, unfortunately, ends right there. A close reading of the Commission’s <a href="https://ec.europa.eu/eusurvey/runner/Future_of_Connectivity#">exploratory consultation</a> that accompanies the Gigabit connectivity proposals shows that the ultimate goal is to intervene in the market for how networks interconnect, with the intention to extract fees from large tech companies and funnel them to large incumbent telcos.</p><p>This debate has been characterised as a fight between Big Tech and Big European Telco. But it’s about much more than that. Contrary to its intent, these proposals would give the biggest technology companies preferred access to the largest European ISPs. European consumers and small businesses, when accessing anything on the Internet outside Big Tech (Netflix, Google, Meta, Amazon, etc), would get the slow lane. Below we’ll explain why Cloudflare, although we are not currently targeted for extra fees, still feels strongly that these fees are dangerous for the Internet:</p><ul><li><p>Network usage fees would create fast lanes for Big Tech content, and slow lanes for everything else, slowing the Internet for European consumers;</p></li><li><p>Small businesses, Internet startups, and consumers are the beneficiaries of Europe’s low wholesale bandwidth prices. Regulatory intervention in this market would lead to higher prices that would be passed onto SMEs and consumers;</p></li><li><p>The Internet works best – fastest and most reliably – when networks connect freely and frequently, bringing content and service as close to consumers as possible. Network usage fees artificially disincentivize efforts to bring content close to users, making the Internet experience worse for consumers.</p></li></ul>
    <div>
      <h3>Why network interconnection matters</h3>
      <a href="#why-network-interconnection-matters">
        
      </a>
    </div>
    <p>Understanding why the debate in Europe matters for the future of the Internet requires understanding how Internet traffic gets to end users, as well as the steps that can be taken to improve Internet performance.</p><p>At Cloudflare, we know a lot about this. According to Hurricane Electric, Cloudflare <a href="https://bgp.he.net/report/exchanges#_participants">connects</a> with other networks at 287 Internet exchange points (IXPs), the second most of any network on the planet. And we’re directly connected to other networks on the Internet in more than 285 cities in over 100 countries. So when we see a proposal to change how networks interconnect, we take notice. What the European Commission is considering might appear to be targeting the direct relationship between telcos and large tech companies, but we know it will have much broader effects.</p><p>There are different ways in which networks exchange data on the Internet. In some cases, networks connect directly to exchange data between users of each network. This is called peering. Cloudflare has an <a href="https://www.cloudflare.com/peering-policy/">open peering policy</a>; we’ll peer with any other network. Peering is one hop between networks – it’s the gold standard. Fewer hops from start to end generally means faster and more reliable data delivery. We peer with more than 12,000 networks around the world on a settlement-free basis, which means neither network pays the other to send traffic. This settlement-free peering is one of the aspects of Cloudflare’s business that allows us to offer a free version of our services to millions of users globally, permitting individuals and small businesses to have websites that load quickly and efficiently and are better protected from cyberattacks. We’ll talk more about the benefits of settlement-free peering below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1MwPHFLIXaM6x0bv4HVkKg/26208e7ac043e0686d988ddbc03782d4/2-2.png" />
            
            </figure><p><i>Figure 1: Traffic takes one of three paths between an end-user’s ISP and the content or service they are trying to access. Traffic could go over direct peering which is 1:1 between the ISP and the content or service provider; it could go through IX Peering which is a many:many connection between networks; or it could go via a transit provider, which is a network that gets compensated for delivering traffic anywhere on the Internet.</i></p><p>When networks don’t connect directly, they might pay a third-party IP transit network to deliver traffic on their behalf. No network is connected to every other network on the Internet, so transit networks play an important role making sure any network can reach any other network. They’re compensated for doing so; generally a network will pay their transit provider based on how much traffic they ask the transit provider to deliver. Cloudflare is connected to more than 12,000 other networks, but there are <a href="https://www-public.imtbs-tsp.eu/~maigron/rir-stats/rir-delegations/world/world-asn-by-number.html">over</a> 100,000 Autonomous Systems (networks) on the Internet, so we use transit networks to reach the “long tail”. For example, the Cloudflare network (AS 13335) provides the website cloudflare.com to any network that requests it. If a user of a small ISP with whom Cloudflare doesn’t have direct connections requests cloudflare.com from their browser, it’s likely that their ISP will use a transit provider to send that request to Cloudflare. Then Cloudflare would respond to the request, sending the website content back to the user via a transit provider.</p><p>In Europe, transit providers play a critical role because many of the largest incumbent telcos won’t do settlement-free direct peering connections. Therefore, many European consumers that use large incumbent telcos for their Internet service interact with Cloudflare’s services through third party transit networks. It isn’t the gold standard of network interconnection (which is peering, and would be faster and more reliable) but it works well enough most of the time.</p><p>Cloudflare would of course be happy to directly connect with EU telcos because we have an <a href="https://www.cloudflare.com/peering-policy/">open peering policy</a>. As we’ll show, the performance and reliability improvement for their subscribers and our customers’ content and services would significantly improve. And if the telcos offered us transit – the ability to send traffic to their network and onwards to the Internet – at market rates, we would consider use of that service as part of competitive supplier selection. While it’s unfortunate that incumbent telcos haven’t offered services at market-competitive prices, overall the interconnection market in Europe – indeed the Internet itself – currently works well. Others agree. BEREC, the body of European telecommunications regulators, <a href="https://www.berec.europa.eu/system/files/2022-10/BEREC%20BoR%20%2822%29%20137%20BEREC_preliminary-assessment-payments-CAPs-to-ISPs_0.pdf">wrote</a> recently in a preliminary assessment:</p><blockquote><p>BEREC's experience shows that the internet has proven its ability to cope with increasing traffic volumes, changes in demand patterns, technology, business models, as well as in the (relative) market power between market players. These developments are reflected in the IP interconnection mechanisms governing the internet which evolved without a need for regulatory intervention. The internet’s ability to self-adapt has been and still is essential for its success and its innovative capability.</p></blockquote><p>There is a competitive market for IP transit. According to market analysis firm Telegeography’s State of the Network 2023 <a href="https://www2.telegeography.com/download-state-of-the-network">report</a>, “The lowest [prices on offer for] 100 GigE [IP transit services in Europe] were $0.06 per Mbps per month.” These prices are consistent with what Cloudflare sees in the market. In our view, the Commission should be proud of the effective competition in this market, and it should protect it. These prices are comparable to IP transit prices in the United States and signal, overall, a healthy Internet ecosystem. Competitive wholesale bandwidth prices (transit prices) mean it is easier for small independent telcos to enter the market, and lower prices for all types of Internet applications and services. In our view, regulatory intervention in this well-functioning market has significant down-side risks.</p><p>Large incumbent telcos are seeking regulatory intervention in part because they are not willing to accept the fair market prices for transit. Very Large Telcos and Content and Application Providers (CAPs) – the term the European Commission uses for networks that have the content and services consumers want to see – negotiate freely for transit and peering. In our experience, large incumbent telcos ask for paid peering fees that are many multiples of what a CAP could pay to transit networks for a similar service. At the prices offered, many networks – including Cloudflare – continue to use transit providers instead of paying incumbent telcos for peering. Telcos are trying to use regulation to force CAPs into these relationships at artificially high prices.</p><p>If the Commission’s proposal is adopted, the price for interconnection in Europe would likely be set by this regulation, not the market. Once there’s a price for interconnection between CAPs and telcos, whether that price is found via negotiation, or more likely arbitrators set the price, that is likely to become the de facto price for all interconnection. After all, if telcos can achieve artificially high prices from the largest CAPs, why would they accept much lower rates from any other network – including transits – to connect with them? Instead of falling wholesale prices spurring Internet innovation as is happening now in Europe and the United States, rising wholesale prices will be passed onto small businesses and consumers.</p>
    <div>
      <h3>Network usage fees would give Big Tech a fast lane, at the expense of consumers and smaller service providers</h3>
      <a href="#network-usage-fees-would-give-big-tech-a-fast-lane-at-the-expense-of-consumers-and-smaller-service-providers">
        
      </a>
    </div>
    <p>If network fees become a reality, the current Internet experience for users in Europe will deteriorate. Notwithstanding existing net neutrality regulations, we already see large telcos relegate content from transit providers to more congested connections. If the biggest CAPs pay for interconnection, consumer traffic to other networks will be relegated to a slow and/or congested lane. Networks that aren’t paying would still use transit providers to reach the large incumbent telcos, but those transit links would be second class citizens to the paid traffic. Existing transit links will become (more) slow and congested. By targeting only the largest CAPs, a proposal based on network fees would perversely, and contrary to intent, cement those CAPs’ position at the top by improving the consumer experience for those networks at the expense of all others. By mandating that the CAPs pay the large incumbent telcos for peering, the European Commission would therefore be facilitating discrimination against services using smaller networks and organisations that cannot match the resources of the large CAPs.</p><p>Indeed, we already see evidence that some of the large incumbent telcos treat transit networks as second-class citizens when it comes to Internet traffic. In November 2022, HWSW, a Hungarian tech news site, <a href="https://www.hwsw.hu/hirek/65357/telekom-cloudflare-peering-ping-packet-loss-deutsche-magyar.html">reported</a> on recurring Internet problems for users of Magyar Telekom, a subsidiary of Deutsche Telekom, because of congestion between Deutsche Telekom and its transit networks:</p><blockquote><p>Network problem that exists during the fairly well-defined period, mostly between 4 p.m. and midnight Hungarian time, … due to congestion in the connection (Level3) between Deutsche Telekom, the parent company that operates Magyar Telekom's international peering routes, and Cloudflare, therefore it does not only affect Hungarian subscribers, but occurs to a greater or lesser extent at all DT subsidiaries that, like Magyar Telekom, are linked to the parent company. (translated by Google Translate)</p></blockquote><p>Going back many years, large telcos have demonstrated that traffic reaching them through transit networks is not a high priority to maintain quality. In 2015, Cogent, a transit provider, <a href="https://www.pacermonitor.com/view/RJPNIWI/Cogent_Communications_Inc_v_Deutsche_Telekom_AG__vaedce-15-01632__0001.0.pdf">sued</a> Deutsche Telekom over interconnection, <a href="https://www.fiercetelecom.com/telecom/cogent-sues-deutsche-telekom-over-congested-interconnection-ports">writing</a>, “Deutsche Telekom has interfered with the free flow of internet traffic between Cogent customers and Deutsche Telekom customers by refusing to increase the capacity of the interconnection ports that allow the exchange of traffic”.</p><p>Beyond the effect on consumers, the implementation of Network Usage Fees would seem to violate the European Union’s Open Internet Regulation, sometimes referred to as the net neutrality provision. Article 3(3) of the Open Internet Regulation <a href="https://digital-strategy.ec.europa.eu/en/policies/open-internet">states</a>:</p><blockquote><p>Providers of internet access services shall treat all traffic equally, when providing internet access services, without discrimination, restriction or interference, <i>and irrespective of the sender and receiver, the content accessed or distributed, the applications or services used or provided</i>, or the terminal equipment used. (emphasis added)</p></blockquote><p>Fees from certain sources of content in exchange for private paths between the CAP and large incumbent telcos would seem to be a plain-language violation of this provision.</p>
    <div>
      <h3>Network usage fees would endanger the benefits of Settlement-Free Peering</h3>
      <a href="#network-usage-fees-would-endanger-the-benefits-of-settlement-free-peering">
        
      </a>
    </div>
    <p>Let’s now talk about the ecosystem that leads to a thriving Internet. We first talked about transit, now we’ll move on to peering, which is quietly central to how the Internet works. “Peering” is the practice of two networks directly interconnecting (they could be backbones, <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">CDNs</a>, mobile networks or broadband telcos to exchange traffic. Almost always, networks peer without any payments (“settlement-free”) in recognition of the performance benefits and resiliency we’re about to discuss. A recent <a href="https://www.pch.net/resources/Papers/peering-survey/PCH-Peering-Survey-2021/PCH-Peering-Survey-2021.pdf">survey</a> of over 10,000 ISPs shows that 99.99% of their exchanged traffic is on settlement-free terms. The Internet works best when these peering arrangements happen freely and frequently.</p><p>These types of peering arrangements and network interconnection also significantly improve latency for the end-user of services delivered via the Internet. The speed of an Internet connection depends more on latency (the time it takes for a consumer to request data and receive the response) than on bandwidth (the maximum amount of data that is flowing at any one time over a connection). Latency is critical to many Internet use-cases. A recent technical <a href="https://datatracker.ietf.org/doc/html/rfc9330">paper</a> used the example of a mapping application that responds to user scrolling. The application wouldn’t need to pre-load unnecessary data if it can quickly get a small amount of data in response to a user swiping in a certain direction.</p><p>In recognition of the myriad benefits, settlement-free peering between CDNs and terminating ISPs is the global norm in the industry. Most networks understand that through settlement-free peering, (1) customers get the best experience through local traffic delivery, (2) networks have increased resilience through multiple traffic paths, and (3) data is exchanged locally instead of backhauled and aggregated in larger volumes at regional Internet hubs. By contrast, paid peering is rare, and is usually employed by networks that operate in markets without robust competition. Unfortunately, when an incumbent telco achieves a dominant market position or has no significant competition, they may be less concerned about the performance penalty they impose on their own users by refusing to peer directly.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7DfB0FAz2CBDWaeFiGzCm/a933e781ab6cc3d3a239e745be4c90e5/Screenshot-2023-05-08-at-9.19.49-AM.png" />
            
            </figure><p>As an example, consider the map in Figure 2. This map shows the situation in Germany, where most traffic is exchanged via transit providers at the Internet hub in Frankfurt. Consumers are losing in this situation for two reasons: First, the farther they are from Frankfurt, the higher latency they will experience for Cloudflare services. For customers in northeast Germany, for example, the distance from Cloudflare’s servers in Frankfurt means they will experience nearly double the latency of consumers closer to Cloudflare geographically. Second, the reliance on a small number of transit providers exposes their traffic to congestion and reliability risks. The remedy is obvious: if large telcos would interconnect (“peer”) with Cloudflare in all five cities where Cloudflare has points of presence, every consumer, regardless of where they are in Germany, would have the same excellent Internet experience.</p><p>We’ve shown that local settlement-free interconnection benefits consumers by improving the speed of their Internet experience, but local interconnection also reduces the amount of traffic that aggregates at regional Internet hubs. If a telco interconnects with a large video provider in a single regional hub, the telco needs to carry their subscribers’ request for content through their network to the hub. Data will be exchanged at the hub, then the telco needs to carry the data back through their “backbone” network to the subscriber. (While this situation can result in large traffic volumes, modern networks can easily expand the capacity between themselves at almost no cost by adding additional port capacity. The fibre-optic cable capacity in this “backbone” part of the Internet is not constrained.)</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5fsvTdNnG7P6QPefRM7RPx/a5564b8ddf68e7c998abbd294fed28d4/4.png" />
            
            </figure><p><i>Figure 3. A hypothetical example where a telco only interconnects with a video provider at a regional Internet hub, showing how traffic aggregates at the interconnection point.</i></p><p>Local settlement-free peering is one way to reduce the traffic across those interconnection points. Another way is to use embedded caches, which are offered by most CDNs, including Cloudflare. In this scenario, a CDN sends hardware to the telco, which installs it in their network at local aggregation points that are private to the telco. When their subscriber requests data from the CDN, the telco can find that content at a local infrastructure point and send it back to the subscriber. The data doesn’t need to aggregate on backhaul links, or ever reach a regional Internet hub. This approach is common. Cloudflare has hundreds of these deployments with telcos globally.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5aElw5KpetUVQmQulidsWx/35e2979b9d454f29c9ce012d2fd117a5/5.png" />
            
            </figure><p><i>Figure 4. A hypothetical example where a telco has deployed embedded caches from a video provider, removing the backhaul and aggregation of traffic across Internet exchange points</i></p>
    <div>
      <h3>Conclusion: make your views known to the European Commission!</h3>
      <a href="#conclusion-make-your-views-known-to-the-european-commission">
        
      </a>
    </div>
    <p>In conclusion, it’s our view that despite the unwillingness of many large European incumbents to peer on a settlement-free basis, the IP interconnection market is healthy, which benefits European consumers. We believe regulatory intervention that forces content and application providers into paid peering agreements would have the effect of relegating all other traffic to a slow, congested lane. Further, we fear this intervention will do nothing to meet Europe’s Digital Decade goals, and instead will make the Internet experience worse for consumers and small businesses.</p><p>There are many more companies, NGOs and politicians that have raised concerns about the impact of introducing network usage fees in Europe. A <a href="https://epicenter.works/document/4660">number of stakeholders</a> have spoken out already about the dangers of regulating the Internet interconnection system; from <a href="https://edri.org/our-work/network-fee-new-attack-on-open-internet/">digital rights groups</a> to the <a href="https://www.politico.eu/article/new-eu-telecom-rules-will-leave-everyone-worse-off-internet-network/">Internet Society</a>, <a href="https://www.europeanvodcoalition.com/content/files/2022/05/Network-fees-position-paper.pdf">European Video on Demand providers</a> and <a href="https://www.acte.be/publication/tv-vod-statement-on-network-fees/">commercial broadcasters</a>, <a href="https://www.euro-ix.net/media/filer_public/c7/72/c772acf6-b286-4edb-a3c5-042090e513df/spnp_impact_on_ixps_-_signed.pdf">Internet Exchanges</a> and <a href="http://mvnoeurope.eu/mvno-europe-position-paper-on-network-investment-contributions/">mobile operators</a> to <a href="https://www.reuters.com/business/media-telecom/germany-others-demand-clarity-eu-plan-telco-network-costs-2022-12-02/">several European governments</a> and <a href="https://www.patrick-breyer.de/wp-content/uploads/2022/07/20220712_COM_Access-Fees-MEP-Letter_final3.pdf">Members of the European Parliament</a>.</p><p>If you agree that major intervention in how networks interconnect in Europe is unnecessary, and even harmful, consider <a href="https://ec.europa.eu/commission/presscorner/detail/en/IP_23_985">reading</a> more about the European Commission’s consultation. While the <a href="https://digital-strategy.ec.europa.eu/en/consultations/future-electronic-communications-sector-and-its-infrastructure">consultation</a> itself may look intimidating, anyone can submit a narrative response (deadline: 19 May). Consider telling the European Commission that their goals of ubiquitous connectivity are the right ones but that the approach they are considering is going into the wrong direction.</p> ]]></content:encoded>
            <category><![CDATA[Interconnection]]></category>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Europe]]></category>
            <category><![CDATA[Peering]]></category>
            <category><![CDATA[Policy & Legal]]></category>
            <guid isPermaLink="false">74ZYxYB8WPMfSdpuXEE7Gy</guid>
            <dc:creator>Petra Arts</dc:creator>
            <dc:creator>Mike Conlow</dc:creator>
        </item>
        <item>
            <title><![CDATA[Measuring network quality to better understand the end-user experience]]></title>
            <link>https://blog.cloudflare.com/aim-database-for-internet-quality/</link>
            <pubDate>Tue, 18 Apr 2023 13:00:00 GMT</pubDate>
            <description><![CDATA[ Starting today, you don’t have to be a network engineer to figure out what your Internet is good for. Let’s tell you how we’re doing it. ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3IimU9cm3fV1XvBvAJwmdE/06aabe48db2f742bfdd6e88a34cdfba6/111.png" />
            
            </figure><p>You’re visiting your family for the holidays and you connect to the WiFi, and then notice Netflix isn’t loading as fast as it normally does. You go to speed.cloudflare.com, fast.com, speedtest.net, or type “speed test” into Google Chrome to figure out if there is a problem with your Internet connection, and get something that looks like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6FH3ra6GdbzBMT650WqWeG/9f9a58e5031c5a7363c07e70b7fdfc5d/112.png" />
            
            </figure><p>If you want to see what that looks like for you, try it yourself <a href="https://speed.cloudflare.com/">here</a>. But what do those numbers mean? How do those numbers relate to whether or not your Netflix isn’t loading or any of the other common use cases: playing games or audio/video chat with your friends and loved ones? Even network engineers find that speed tests are difficult to relate to the user experience of… using the Internet.</p><p>Amazingly, speed tests have barely changed in nearly two decades, even though the way we use the Internet has changed a lot. With so many more people on the Internet, the gaps between speed tests and the user’s experience of network quality are growing. The problem is so important that the Internet’s standards organization is <a href="https://datatracker.ietf.org/doc/rfc9318/">paying attention</a>, too.</p><p>From a high-level, there are three grand network test challenges:</p><ol><li><p>Finding ways to efficiently and accurately measure network quality, and convey to end-users if and how the quality affects their experience.</p></li><li><p>When a problem is found, figuring out where the problem exists, be it the wireless connection, or one many cables and machines that make up the Internet.</p></li><li><p>Understanding a single user’s test results in context of their neighbors’, or archiving the results to, for example, compare neighborhoods or know if the network is getting better or worse.</p></li></ol><p>Cloudflare is excited to announce a new Aggregated Internet Measurement (AIM) initiative to help address all three challenges. AIM is a new and open format for displaying Internet quality in a way that makes sense to end users of the Internet, around use cases that demand specific types of Internet performance while still retaining all of the network data engineers need to troubleshoot problems on the Internet. We’re excited to partner with <a href="https://www.measurementlab.net/">Measurement Lab</a> on this project and store all of this data in a <a href="https://colab.research.google.com/drive/1xgc-7L1Okr04MSjsYJfiFeUN0Gu05bpQ?usp=sharing">publicly available repository</a> that you can access to analyze the data behind the scores you see on your speed test page, whose source code is <a href="https://github.com/cloudflare/speedtest">now open-sourced</a> along with the AIM score calculations.</p>
    <div>
      <h2>What is a speed test?</h2>
      <a href="#what-is-a-speed-test">
        
      </a>
    </div>
    <p>A speed test is a point-in-time measurement of your Internet connection. When you connect to any speed test, it typically tries to fetch a large file (important for <a href="https://www.cloudflare.com/developer-platform/solutions/live-streaming/">video streaming</a>), performs a packet loss test (important for gaming), measures jitter (important for video/VoIP calls), and latency (important for all Internet use cases). The goal of this test is to measure your Internet connection’s ability to perform basic tasks.</p><p>There are some challenges with this approach that start with a simple observation: At the “<a href="https://www.cloudflare.com/learning/network-layer/what-is-the-network-layer/">network-layer</a>” of the Internet that moves data and packets around, there are three and only three measures that can be directly observed. They are,</p><ul><li><p>available <i>bandwidth</i>, sometimes known as “throughput”;</p></li><li><p>packet <i>loss,</i> which occurs at extremely low levels throughout the Internet at steady state_;_ and</p></li><li><p><i>latency</i>, often referred to as the <a href="https://www.cloudflare.com/learning/cdn/glossary/round-trip-time-rtt/">round-trip time (RTT)</a>.</p></li></ul><p>These three attributes are tightly interwoven. In particular, the portion of available bandwidth that a user actually achieves (throughput) is directly affected by loss and latency. Your computer uses loss and latency to decide when to send a packet, or not. Some loss and latency is expected, even needed! Too much of either, and bandwidth starts to fall.</p><p>These are simple numbers, but their relationship is far from simple. Think about all the ways to add two numbers to equal <i>as much as</i> one-hundred, x + y ≤ 100. If x and y are just right, then they add to one hundred. However, there are many combinations of x and y that do. Worse is that if either x or y or both are a little wrong, then they add to less than one-hundred. In this example, x and y are loss and latency, and 100 is the available bandwidth.</p><p>There are other forces at work, too, and these numbers do not tell the whole story. But they are the only numbers that are directly observable. Their meaning and the reasons they matter for diagnosis are important, so let’s discuss each one of those in order and how Aggregated Internet Measurement tries to solve each of these.</p>
    <div>
      <h2>What do the numbers in a speed test mean?</h2>
      <a href="#what-do-the-numbers-in-a-speed-test-mean">
        
      </a>
    </div>
    <p>Most speed tests will run and produce the numbers you saw above: bandwidth, latency, jitter, and packet loss. Let’s break down each of these numbers one by one to explain what they mean:</p>
    <div>
      <h3>Bandwidth</h3>
      <a href="#bandwidth">
        
      </a>
    </div>
    <p>Bandwidth is the maximum throughput/capacity over a communication link. The common analogy used to define bandwidth is if your Internet connection is a highway, bandwidth is how many lanes the highway has and cars that fit on it. Bandwidth has often been called “speed” in the past because Internet Service Providers (ISPs) measure speed as the amount of time it takes to download a large file, and having more bandwidth on your connection can make that happen faster.</p>
    <div>
      <h3>Packet loss</h3>
      <a href="#packet-loss">
        
      </a>
    </div>
    <p>Packet loss is exactly what it sounds like: some packets are sent from a source to a destination, but the packets are not received by the destination. This can be very impactful for many applications, because if information is lost in transit en route to the receiver, it an e ifiult fr te recvr t udrsnd wt s bng snt (it can be difficult for the receiver to understand what is being sent).</p>
    <div>
      <h3>Latency</h3>
      <a href="#latency">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/performance/glossary/what-is-latency/">Latency</a> is the time it takes for a packet/message to travel from point A to point B. At its core, the Internet is composed of computers sending signals in the form of electrical signals or beams of light over cables to other computers. Latency has generally been defined as the time it takes for that electrical signal to go from one computer to another over a cable or fiber. Therefore, it follows that one way to reduce latency is to shrink the distance the signals need to travel to reach their destination.</p><p>There is a distinction in latency between idle latency and latency under load. This is because there are queues at routers and switches that store data packets when they arrive faster than they can be transmitted. Queuing is normal, by design, and keeps data flowing correctly. However, if the queues are too big, or when other applications behave very differently from yours, the connection can feel slower than it actually is. This event is called <a href="https://www.bufferbloat.net/projects/">bufferbloat</a>.</p><p>In our AIM test we look at idle latency to show you what your latency <i>could</i> be, but we also collect loaded latency, which is a better reflection of what your latency is during your day-to-day Internet experience.</p>
    <div>
      <h3>Jitter</h3>
      <a href="#jitter">
        
      </a>
    </div>
    <p>Jitter is a special way of measuring latency. It is the variance in latency on your Internet connection. If jitter is high, it may take longer for some packets to arrive, which can impact Internet scenarios that require content to be delivered in real time, such as voice communication.</p><p>A good way to think about jitter is to think about a commute to work along some route or path. Latency, alone, asks “how far am I from the destination measured in time?” For example, the average journey on a train is 40 minutes. Instead of journey time, jitter asks, “how consistent is my travel time?” Thinking about the commute, a jitter of zero means the train always takes 40 minutes. However, if the jitter is 15 then, well, the commute becomes a lot more challenging because it could take anywhere from 25 to 55 minutes.</p><p>But even if we understand these numbers, for all that they might tell us <i>what</i> is happening, they are unable to tell us <i>where</i> something is happening.</p>
    <div>
      <h2>Is WiFi or my Internet connection the problem?</h2>
      <a href="#is-wifi-or-my-internet-connection-the-problem">
        
      </a>
    </div>
    <p>When you run a speed test, you’re not just connecting to your ISP, you’re also connecting to your local network which connects to your ISP. And your local network may have problems of its own. Take a speed test that has high packet loss and jitter: that generally means something on the network could be dropping packets. Normally, you would call your ISP, who will often say something like “get closer to your WiFi access point or get an extender”.</p><p>This is important — WiFi uses radio waves to transmit information, and materials like brick, plaster, and concrete can interfere with the signal and make it weaker the farther away you get from your access point. Mesh WiFi appliances like Nest WiFi and Eero periodically take speed tests from their main access point specifically to help detect issues like this. So having <a href="https://developers.cloudflare.com/fundamentals/speed/aim/">potential quick solutions</a> for problems like high packet loss and jitter and giving that to users up front can help users better ascertain if the problem is related to their wireless connection setup.</p><p>While this is true for most issues that we see on the Internet, it often helps if network operators are able to look at this data in aggregate in addition to simply telling users to get closer to their access points. If your speed test went to a place where your network operator could see it and others in your area, network engineers may be able to proactively detect issues before users report them. This not only helps users, it helps network providers as well, because fielding calls and sending out technicians for issues due to user configuration are expensive in addition to being time consuming.</p><p>This is one of the goals of AIM: to help solve the problem before anyone picks up a phone. End users can get a series of tips that will help them understand what their Internet connection can and can’t do and how they can improve it in an easy-to-read format, and network operators can get all the data they need to detect last mile issues before anyone picks up a phone, saving time and money. Let’s talk about how that can work with a real example.</p>
    <div>
      <h2>An example from a real life</h2>
      <a href="#an-example-from-a-real-life">
        
      </a>
    </div>
    <p>When you get a speed test result, the numbers you get can be confusing. This is because you may not understand how those numbers combine to impact your Internet experience. Let’s talk about a real life example and how that impacts you.</p><p>Say you work in a building with four offices and a main area that looks like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4mI2OjDE4asb8FmKeHtJCP/a0e9c36be7927a996729a833f3f9457a/113.png" />
            
            </figure><p>You have to make video calls to her clients all day and you sit in the office farthest away from the wireless access point. Your calls are dropping constantly and you’re having a really bad experience. When you runs a speed test from her office, she sees this result:</p>
<table>
<thead>
  <tr>
    <th><span>Metric</span></th>
    <th><span>Far away from access point</span></th>
    <th><span>Close to access point</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Download Bandwidth</span></td>
    <td><span>21.8 Mbps</span></td>
    <td><span>25.7 Mbps</span></td>
  </tr>
  <tr>
    <td><span>Upload Bandwidth</span></td>
    <td><span>5.66 Mbps</span></td>
    <td><span>5.26 Mbps</span></td>
  </tr>
  <tr>
    <td><span>Unloaded Latency</span></td>
    <td><span>19.6 ms</span></td>
    <td><span>19.5 ms</span></td>
  </tr>
  <tr>
    <td><span>Jitter</span></td>
    <td><span>61.4 ms</span></td>
    <td><span>37.9 ms</span></td>
  </tr>
  <tr>
    <td><span>Packet Loss</span></td>
    <td><span>7.7%</span></td>
    <td><span>0%</span></td>
  </tr>
</tbody>
</table><p>How can you make sense of these? A network engineer would take a look at the high jitter and the packet loss and think “well this user probably needs to move closer to the router to get a better signal”. But you may take a look at these results and have no idea, and have to ask a network engineer for help, which could lead to a call to your ISP, wasting the time and money of everyone. But you shouldn’t have to consult a network engineer to figure out if you need to move your WiFi access point, or if your ISP isn’t giving her a good experience.</p><p>Aggregated Internet Measurement assigns qualitative assessments to the numbers on your speed test to help you make sense of these numbers. We’ve created scenario-specific scores, which is a singular qualitative value that is calculated on a scenario level: we calculate different quality scores based on what you’re trying to do. To start, we’ve created three AIM scores: Streaming, Gaming, and WebChat/RTC. Those scores weigh each metric differently based on what Internet conditions are required for the application to run successfully.</p><p>The AIM scoring rubric assigns point values to your connection based on the tests. We’re releasing AIM with a “weighted score,” in which the point values are calculated based on what metrics matter the most in those scenarios. These point scores aren’t designed to be static, but to evolve based on what application developers, network operators, and the Internet community discover about how different performance characteristics affect application experience for each scenario – and it’s one more reason to post the data to M-Lab, so that the community can help design and converge on good scoring mechanisms.</p><p>Here is the full rubric and each of the point values associated with the metrics today:</p>
<table>
<thead>
  <tr>
    <th><span>Metric</span></th>
    <th><span>0 points</span></th>
    <th><span>5 points</span></th>
    <th><span>10 points</span></th>
    <th><span>20 points</span></th>
    <th><span>30 points</span></th>
    <th><span>50 points</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Loss Rate</span></td>
    <td><span>&gt; 5%</span></td>
    <td><span>&lt; 5%</span></td>
    <td><span>&lt; 1%</span></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Jitter</span></td>
    <td><span>&gt; 20 ms</span></td>
    <td><span>&lt; 20ms</span></td>
    <td><span>&lt; 10ms</span></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Unloaded latency</span></td>
    <td><span>&gt; 100ms</span></td>
    <td><span>&lt; 50ms</span></td>
    <td><span>&lt; 20ms</span></td>
    <td><span>&lt; 10ms</span></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Download Throughput</span></td>
    <td><span>&lt; 1Mbps</span></td>
    <td><span>&lt; 10Mbps</span></td>
    <td><span>&lt; 50Mbps</span></td>
    <td><span>&lt; 100Mbps</span></td>
    <td><span>&lt; 1000Mbps</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Upload Throughput</span></td>
    <td><span>&lt; 1Mbps</span></td>
    <td><span>&lt; 10Mbps</span></td>
    <td><span>&lt; 50Mbps</span></td>
    <td><span>&lt; 100Mbps</span></td>
    <td><span>&lt; 1000Mbps</span></td>
    <td></td>
  </tr>
  <tr>
    <td><span>Difference between loaded and unloaded latency</span></td>
    <td><span>&gt; 50ms</span></td>
    <td><span>&lt; 50ms</span></td>
    <td><span>&lt; 20ms</span></td>
    <td><span>&lt; 10ms</span></td>
    <td></td>
    <td></td>
  </tr>
</tbody>
</table><p>And here’s a quick overview of what values matter and how we calculate scores for each scenario:</p><ul><li><p>Streaming: download bandwidth + unloaded latency + packet loss + (loaded latency - unloaded latency difference)</p></li><li><p>Gaming: packet loss + unloaded latency + (loaded latency - unloaded latency difference)</p></li><li><p>RTC/video: packet loss + jitter + unloaded latency + (loaded latency - unloaded latency difference)</p></li></ul><p>To calculate each score, we take the point values from your speed test and calculate that out of the total possible points for that scenario. So based on the result, we can give your Internet connection a judgment for each scenario: Bad, Poor, Average, Good, and Great. For example, for Video calls, packet loss, jitter, unloaded latency, and the difference between loaded and unloaded latency matter when determining whether or not your Internet quality is good for video calls. We add together the point values derived from your speed test values and we get a score that shows how far away from the perfect video call experience your Internet quality is. Based on your speed test, here are the AIM scores from your office far away from the access point:</p>
<table>
<thead>
  <tr>
    <th><span>Metric</span></th>
    <th><span>Result</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Streaming Score</span></td>
    <td><span>25/70 pts (Average)</span></td>
  </tr>
  <tr>
    <td><span>Gaming Score</span></td>
    <td><span>15/40 pts (Poor)</span></td>
  </tr>
  <tr>
    <td><span>RTC Score</span></td>
    <td><span>15/50 pts (Average)</span></td>
  </tr>
</tbody>
</table><p>So instead of saying “Your bandwidth is X and your jitter is Y”, we can say “Your Internet is okay for Netflix, but poor for gaming, and only average for Zoom”. In this case, moving the WiFi access point to a more centralized location turned out to be the solution, and turned your AIM scores into this:</p>
<table>
<thead>
  <tr>
    <th><span>Metric</span></th>
    <th><span>Result</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Streaming Score</span></td>
    <td><span>45/70 pts (Good)</span></td>
  </tr>
  <tr>
    <td><span>Gaming Score</span></td>
    <td><span>35/40 pts (Great)</span></td>
  </tr>
  <tr>
    <td><span>RTC Score</span></td>
    <td><span>35/50 pts (Great)</span></td>
  </tr>
</tbody>
</table><p>You can even see these results on the Cloudflare speed test today as a Network Quality Score:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/CrZxqJ79VLN4MM6O0gMOX/440836054b316ba12616cb623b6ecd0f/114.png" />
            
            </figure><p>In this particular case, there was no call required to the ISP, and no network engineers were consulted. Simply moving the access point closer to the middle of the office improved the experience for everyone, and no one needed to pick up the phone, providing a more seamless experience for everyone.</p><p>AIM takes the metrics that network engineers care about and it translates them into a more human-readable metric that’s based on the applications you are trying to use. Aggregated data is anonymous (in compliance with our <a href="https://www.cloudflare.com/privacypolicy/">privacy policy</a>), so that your ISP can actually look up speed tests in your metro area and that use your ISP and get the underlying data to help translate user complaints into something that is actionable by network engineers. Additionally, policy makers and researchers can examine the aggregate data to better understand what users in their communities are experiencing to help lobby for better Internet quality.</p>
    <div>
      <h2>Working conditions</h2>
      <a href="#working-conditions">
        
      </a>
    </div>
    <p>Here’s an interesting question: When you run a speed test, where are you connecting to and what is the Internet like at the other end of the connection? One of the challenges that speed tests often face is that the servers you run your test against are not the same servers that run or protect your websites. Because of this, the network paths your speed test may take to the host on the other side may be vastly different, and may even be optimized to serve as many speed tests as possible. This means that your speed test is not actually testing the path that your traffic normally takes when it’s reaching the applications you normally use. The tests that you ran are measuring a network path, but it’s not the network path you use on a regular basis.</p><p>Speed tests should be run under real-world network conditions that reflect how people use the Internet, with multiple applications, browser tabs, and devices all competing for connectivity. This concept of measuring your Internet connection using application-facing tools and doing so while your network is being used as much as possible is called measuring under working conditions. Today, when speed tests run, they make entirely new connections to a website that is reserved for testing network performance. Unfortunately, day-to-day Internet usage isn’t done on new connections to dedicated speed test websites. This is actually by design for many Internet applications, which rely on reusing the same connection to a website to provide a better performing experience to the end-user by eliminating costly latency incurred by establishing encryption, exchanging of certificates, and more.</p><p>AIM is helping to solve this problem in several ways. The first is that we’ve implemented all of our tests the same way our applications would, and measure them under working conditions. We measure loaded latency to show you how your Internet connection behaves when you’re actually using it. You can see it on the speed test today:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7HSlY2m75rAmNht9BuCjZc/9ff7bf8ea97bd8f49fa0ae46d8c487eb/Screenshot-2023-02-10-at-11.43.27.png" />
            
            </figure><p>The second is that we are collecting speed test results against endpoints that you use today. By measuring speed tests against Cloudflare and other sites, we are showing end user Internet quality against networks that are frequently used in your daily life, which gives a better idea of what actual working conditions are.</p>
    <div>
      <h2>AIM database</h2>
      <a href="#aim-database">
        
      </a>
    </div>
    <p>We’re excited to announce that AIM data is <a href="https://colab.research.google.com/drive/1xgc-7L1Okr04MSjsYJfiFeUN0Gu05bpQ?usp=sharing">publicly available today</a> through a partnership with Measurement Lab (M-Lab), and end-users and network engineers alike can parse through network quality data across a variety of networks. M-Lab and Cloudflare will both be calculating AIM scores derived from their speed tests and putting them into a shared database so end-users and network operators alike can see Internet quality from as many points as possible across a multitude of different speed tests.</p><p>For just a sample of what we’re seeing, let’s take a look at a visual we’ve made using this data plotting scores from only Cloudflare data per scenario in Tokyo, Japan for the first week of October:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4AVAz6PoQwTJszzgx0Bi3Z/32e6ad5e435711d326e0d5810726eb13/116.png" />
            
            </figure><p>Based on this, you can see that out of the 5,814 speed tests run, 50.7% of those users had a good streaming quality, but 48.2% were only average. Gaming appears to be relatively hard in Tokyo as 39% of users had a poor gaming experience, but most users had a pretty average-to-decent RTC experience. Let’s take a look at how that compares to some of the other cities we see:</p>
<table>
<thead>
  <tr>
    <th><span>City</span></th>
    <th><span>Average Streaming Score</span></th>
    <th><span>Average Gaming Score</span></th>
    <th><span>Average RTC Score</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Tokyo</span></td>
    <td><span>31</span></td>
    <td><span>13</span></td>
    <td><span>16</span></td>
  </tr>
  <tr>
    <td><span>New York</span></td>
    <td><span>33</span></td>
    <td><span>13</span></td>
    <td><span>17</span></td>
  </tr>
  <tr>
    <td><span>Mumbai</span></td>
    <td><span>25</span></td>
    <td><span>13</span></td>
    <td><span>16</span></td>
  </tr>
  <tr>
    <td><span>Dublin</span></td>
    <td><span>32</span></td>
    <td><span>14</span></td>
    <td><span>18</span></td>
  </tr>
</tbody>
</table><p>Based on our data, we can see that most users do okay for video streaming except for Mumbai, which is a bit behind. Users generally have a variable gaming experience due to high latency being the primary driver behind the gaming score, but their RTC apps do slightly better, being generally average in all the locales.</p>
    <div>
      <h2>Collaboration with M-Lab</h2>
      <a href="#collaboration-with-m-lab">
        
      </a>
    </div>
    <p>M-Lab is an open, Internet measurement repository whose mission is to measure the Internet, save the data, and make it universally accessible and useful. In addition to providing free and open access to the AIM data for network operators, M-Lab will also be giving policy makers, academic researchers, journalists, digital inclusion advocates, and anyone who is interested access to the data they need to make important decisions that can help improve the Internet.</p><p>In addition to already being an established name in open sharing of Internet quality data to policy makers and academics, M-Lab already provides a “speed” test called Network Diagnostic Test (NDT) that is the same speed test you run when you type “speed test” into Google. By partnering with M-Lab, we are getting Aggregated Internet Measurement metrics from many more users. We want to partner with other speed tests as well to get the complete picture of how Internet quality is mapped across the world for as many users as possible. If you measure Internet performance today, we want you to join us to help show users what their Internet is really good for.</p>
    <div>
      <h2>Speed test, now open sourced</h2>
      <a href="#speed-test-now-open-sourced">
        
      </a>
    </div>
    <p>In addition to partnering with M-Lab, we’ve also open-sourced our speed test client. Open-sourcing the speed test is an important step towards giving applications access to speed measurements through Cloudflare, and an easy way to start calculating AIM scores for your application. Our speed test is now embeddable as a javascript application so that you can perform network quality tests without needing to navigate to the browser. The application not only provides you all of the measurements we use for our speed test today, but also uploads the results in a private fashion to Cloudflare. The repository also shows how we are calculating the AIM scores, so that you can see the inner workings of how network quality is being defined to end-users and how that changes in real-time. To get started developing with our open-source speed test, check out the <a href="https://github.com/cloudflare/speedtest">open-source link</a>.</p>
    <div>
      <h2>A bright future for Internet quality</h2>
      <a href="#a-bright-future-for-internet-quality">
        
      </a>
    </div>
    <p>We’re excited to put this data together to show Internet quality across a variety of tests and networks. We’re going to be analyzing this data and improving our scoring system, and we’ve open-sourced it so that you can see how we are using speed test measurements to score Internet quality across a variety of different applications and even implement AIM yourself. We’ve also put our AIM scores in the speed test alongside all of the tests you see today so that you can finally get a better understanding of what your Internet is good for.</p><p>If you’re running a speed test today and you’re interested in partnering with us to help gather data on how users experience Internet quality, <a>reach out</a> to us and let’s work together to help make the Internet better. And if you’re running an application that wants to measure Internet quality, check out our <a href="https://github.com/cloudflare/speedtest">open source repo</a> so that you can start developing today.</p><p>Figuring out what your Internet is good for shouldn’t require you to become a networking expert; that’s what we’re here for. With AIM and our collaborators at MLab, we want to be able to tell you what your Internet can do and use that information to help <a href="https://blog.cloudflare.com/50-years-of-the-internet-work-in-progress-to-a-better-internet/">make the Internet better</a> for everyone.</p> ]]></content:encoded>
            <category><![CDATA[Network]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Internet Quality]]></category>
            <guid isPermaLink="false">6uJzPTICOVrX9qkT9solfp</guid>
            <dc:creator>David Tuber</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare partners to simplify China connectivity for corporate networks]]></title>
            <link>https://blog.cloudflare.com/cloudflare-one-in-china/</link>
            <pubDate>Tue, 29 Nov 2022 16:35:47 GMT</pubDate>
            <description><![CDATA[ Today we’re excited to announce expansion of our Cloudflare One product suite to tackle these problems, with the goal of creating the best SASE experience for users and organizations in China ]]></description>
            <content:encoded><![CDATA[ <p><i></i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/59bEi3ASQdbRkn2o4KBhIp/14f5f5a20f816a36f1a48100134f8443/image2-57.png" />
            
            </figure><p>IT teams have historically faced challenges with performance, security, and reliability for employees and network resources in mainland China. Today, along with our strategic partners, we’re excited to announce expansion of our Cloudflare One product suite to tackle these problems, with the goal of creating the best <a href="https://www.cloudflare.com/learning/access-management/what-is-sase/">SASE</a> experience for users and organizations in China.</p><p>Cloudflare One, our comprehensive SASE platform, allows organizations to connect any source or destination and apply single-pass security policies from one unified control plane. Cloudflare One is built on our <a href="https://www.cloudflare.com/network/">global network</a>, which spans 275 cities across the globe and is within 50ms of 95% of the world’s Internet-connected population. Our ability to serve users extremely close to wherever they’re working—whether that’s in a corporate office, their home, or a <a href="https://www.cloudflare.com/learning/access-management/coffee-shop-networking/">coffee shop</a>—has been a key reason customers choose our platform since day one.</p><p>In 2015, we extended our <a href="https://www.cloudflare.com/application-services/">Application Services</a> portfolio to cities in mainland China; in 2020, we expanded these capabilities to offer better performance and security through our strategic partnership with <a href="/cloudflare-partners-with-jd-cloud/">JD Cloud</a>. Today, we’re unveiling our latest steps in this journey: extending the capabilities of Cloudflare One to users and organizations in mainland China, through additional strategic partnerships. Let’s break down a few ways you can achieve better connectivity, security, and performance for your China network and users with Cloudflare One.</p>
    <div>
      <h3>Accelerating traffic from China networks to private or public resources outside of China through China partner networks</h3>
      <a href="#accelerating-traffic-from-china-networks-to-private-or-public-resources-outside-of-china-through-china-partner-networks">
        
      </a>
    </div>
    <p>Performance and reliability for traffic flows across the mainland China border have been a consistent challenge for IT teams within multinational organizations. Packets crossing the China border often experience reachability, congestion, loss, and latency challenges on their way to an origin server outside of China (and vice versa on the return path). Security and IT teams can also struggle to enforce consistent policies across this traffic, since many aspects of China networking are often treated separately from the rest of an organization’s global network because of their unique challenges.</p><p>Cloudflare is excited to address these challenges with our strategic China partners, combining our network infrastructure to deliver a better end-to-end experience to customers. Here’s an example architecture demonstrating the optimized packet flow with our partners and Cloudflare together:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/doTXbrCkWraGqKxZeLky4/6899fdb9b2492b3f150cceff8beefef0/1-7.png" />
            
            </figure><p>Acme Corp, a multinational organization, has offices in Shanghai and Beijing. Users in those offices need to reach resources hosted in Acme’s data centers in Ashburn and London, as well as SaaS applications like Jira and Workday. Acme procures last mile connectivity at each office in mainland China from Cloudflare’s China partners.</p><p>Cloudflare’s partners route local traffic to its destination within China, and global traffic across a secure link to the closest available Cloudflare data center on the other side of the Chinese border.</p><p>At that data center, Cloudflare enforces a full stack of security functions across the traffic including network <a href="https://www.cloudflare.com/learning/cloud/what-is-a-cloud-firewall/">firewall-as-a-service</a> and Secure Web Gateway policies. The traffic is then routed to its destination, whether that’s another connected location on Acme’s private network (via Anycast GRE or IPsec tunnel or <a href="https://www.cloudflare.com/network-interconnect/">direct connection</a>) or a resource on the public Internet, across an optimized middle-mile path. Acme can choose whether Internet-bound traffic egresses from a shared or dedicated Cloudflare-owned IP pool.</p><p>Return traffic back to Acme’s connected network location in China takes the opposite path: source → Cloudflare’s network (where, again, security policies are applied) → Partner network → Acme local network.</p><p>Cloudflare and our partners are excited to help customers solve challenges with cross-border performance and security. This <a href="https://www.cloudflare.com/application-services/solutions/">solution</a> is easy to deploy and available now - reach out to your account team to get started today.</p>
    <div>
      <h3>Enforcing uniform security policy across remote China user traffic</h3>
      <a href="#enforcing-uniform-security-policy-across-remote-china-user-traffic">
        
      </a>
    </div>
    <p>The same challenges that impact connectivity from China-based networks reaching out to global resources also impact remote users working in China. Expanding on the network connectivity solution we just described, we’re looking forward to improving user connectivity to cross-border resources by adapting our device client (WARP). This solution will also allow security teams to enforce consistent policy across devices connecting to corporate resources, rather than managing separate security stacks for users inside and outside of China.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7aU3IiM5L9cZa0n6oQvd7q/669873c7e709dc2e18e271defe8e84a4/2-2.png" />
            
            </figure><p>Acme Corp has users that are either based in or traveling to China for business and need to access corporate resources that are hosted beyond China, without necessarily being physically in an Acme office in order to enable this access. Acme uses an MDM provider to install the WARP client on company-managed devices and enroll them in Acme’s Cloudflare Zero Trust organization. Within China, the WARP client utilizes Cloudflare’s China partner networks to establish the same Wireguard tunnel to the nearest Cloudflare point of presence outside of mainland China. Cloudflare’s partners act as the carrier of our customers’ IP traffic through their acceleration service and the content remains secure inside WARP.</p><p>Just as with traffic routed via our partners to Cloudflare at the network layer, WARP client traffic arriving at its first stop outside of China is filtered through Gateway and Access policies. Acme’s IT administrators can choose to enforce the same, or additional policies for device traffic from China vs other global locations. This setup makes life easier for Acme’s IT and security teams - they only need to worry about installing and managing a single device client in order to grant access and control security regardless of where employees are in the world.</p><p>Cloudflare and our partners are actively testing this solution in private beta. If you’re interested in getting access as soon as it’s available to the broader public, please contact your account team.</p>
    <div>
      <h3>Extending SASE filtering to local China data centers (future)</h3>
      <a href="#extending-sase-filtering-to-local-china-data-centers-future">
        
      </a>
    </div>
    <p>The last two use cases have focused primarily on granting network and user access from within China to resources on the other side of the border - but what about improving connectivity and security for local traffic?</p><p>We’ve heard from both China-based and multinational organizations that are excited to have the full suite of Cloudflare One functions available across China to achieve a full SASE architecture just a few milliseconds from everywhere their users and applications are in the world. We’re actively working toward this objective with our strategic partners, expanding upon the current availability of our application services platform across 45 data centers in 38 unique cities in mainland China.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/UxurdJVTv7uXteViJbplD/232f198ea2e618df95c9db12bcc934e8/image4-36.png" />
            
            </figure><p>Talk to your account team today to get on the waitlist for the full suite of Cloudflare One functions delivered across our China Network and be notified as soon as beta access is available!</p>
    <div>
      <h3>Get started today</h3>
      <a href="#get-started-today">
        
      </a>
    </div>
    <p>We’re so excited to help organizations improve connectivity, performance and security for China networks and users. Contact your account team today to learn more about how Cloudflare One can help you transform your network and achieve a SASE architecture inside and outside of mainland China.</p><p>If you'd like to learn more, join us for a live webinar on Dec 6, 2022 10:00 AM PST through this <a href="https://gateway.on24.com/wcc/eh/2153307/lp/4010917/navigating-the-challenges-of-connecting-with-your-audience-in-china?partnerref=blog">link</a> where we can answer all your questions about connectivity in China.</p> ]]></content:encoded>
            <category><![CDATA[China]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">3qxWHx7DkFzf8F2FAc6UDl</guid>
            <dc:creator>Kyle Krum</dc:creator>
            <dc:creator>Annika Garbers</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare servers don't own IPs anymore – so how do they connect to the Internet?]]></title>
            <link>https://blog.cloudflare.com/cloudflare-servers-dont-own-ips-anymore/</link>
            <pubDate>Fri, 25 Nov 2022 14:00:00 GMT</pubDate>
            <description><![CDATA[ In this blog we'll discuss how we manage Cloudflare IP addresses
used to retrieve the data from the Internet, how our egress
network design has evolved, how we optimized it for best use
of available IP space and introduce our soft-anycast technology ]]></description>
            <content:encoded><![CDATA[ <p><i></i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/27jjBnvTr1dvuTNt8baVMj/5244e0d8f89ffd15d4bf51a15e646625/image11-3.png" />
            
            </figure><p>A lot of Cloudflare's technology is well documented. For example, how we handle traffic between the eyeballs (clients) and our servers has been discussed many times on this blog: “<a href="/a-brief-anycast-primer/">A brief primer on anycast (2011)</a>”, "<a href="/cloudflares-architecture-eliminating-single-p/">Load Balancing without Load Balancers (2013)</a>", "<a href="/path-mtu-discovery-in-practice/">Path MTU discovery in practice (2015)</a>",  "<a href="/unimog-cloudflares-edge-load-balancer/">Cloudflare's edge load balancer (2020)</a>", "<a href="/tubular-fixing-the-socket-api-with-ebpf/">How we fixed the BSD socket API (2022)</a>".</p><p>However, we have rarely talked about the second part of our networking setup — how our servers fetch the content from the Internet. In this blog we’re going to cover this gap. We'll discuss how we manage Cloudflare IP addresses used to retrieve the data from the Internet, how our egress network design has evolved and how we optimized it for best use of available IP space.</p><p>Brace yourself. We have a lot to cover.</p>
    <div>
      <h3>Terminology first!</h3>
      <a href="#terminology-first">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/01iopATg1CQGchxawLCk1U/9d8582351fed8929930c18c78321f194/image8-4.png" />
            
            </figure><p>Each Cloudflare server deals with many kinds of networking traffic, but two rough categories stand out:</p><ul><li><p><i>Internet sourced traffic</i> - Inbound connections initiated by eyeball to our servers. In the context of this blog post we'll call these "<b>ingress</b> connections".</p></li><li><p><i>Cloudflare sourced traffic</i> - Outgoing connections initiated by our servers to other hosts on the Internet. For brevity, we'll call these "<b>egress</b> connections".</p></li></ul><p>The egress part, while rarely discussed on this blog, is critical for our operation. Our servers must initiate outgoing connections to get their jobs done! Like:</p><ul><li><p>In our CDN product, before the content is cached, it's fetched from the origin servers. See "<a href="/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/">Pingora, the proxy that connects Cloudflare to the Internet (2022)</a>", <a href="/argo-v2/">Argo</a> and <a href="/tiered-cache-smart-topology/">Tiered Cache</a>.</p></li><li><p>For the <a href="https://www.cloudflare.com/products/cloudflare-spectrum/">Spectrum</a> product, each ingress TCP connection results in one egress connection.</p></li><li><p><a href="https://workers.cloudflare.com/">Workers</a> often run multiple subrequests to construct an HTTP response. Some of them might be querying servers to the Internet.</p></li><li><p>We also operate client-facing forward proxy products - like WARP and Cloudflare Gateway. These proxies deal with eyeball connections destined to the Internet. Our servers need to establish connections to the Internet on behalf of our users.</p></li></ul><p>And so on.</p>
    <div>
      <h3>Anycast on ingress, unicast on egress</h3>
      <a href="#anycast-on-ingress-unicast-on-egress">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/WOoxT0QUqaGhBwa0lSgRu/15aba7b2dbf84e647d84dfa3a5adeeb2/image9-3.png" />
            
            </figure><p>Our ingress network architecture is very different from the egress one. On ingress, the connections sourced from the Internet are handled exclusively by our anycast IP ranges. Anycast is a technology where each of our data centers "announces" and can handle the same IP ranges. With many destinations possible, how does the Internet know where to route the packets? Well, the eyeball packets are routed towards the closest data center based on Internet BGP metrics, often it's also geographically the closest one. Usually, the BGP routes don't change much, and each eyeball IP can be expected to be routed to a single data center.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7jiVD7EKAKmWRoIN6FlrMz/f7b12c24fcf94a56e44638f3f74f955a/image10-2.png" />
            
            </figure><p>However, while anycast works well in the ingress direction, it can't operate on egress. Establishing an outgoing connection from an anycast IP won't work. Consider the response packet. It's likely to be routed back to a wrong place - a data center geographically closest to the sender, not necessarily the source data center!</p><p>For this reason, until recently, we established outgoing connections in a straightforward and conventional way: each server was given its own unicast IP address. "Unicast IP" means there is only one server using that address in the world. Return packets will work just fine and get back exactly to the right server identified by the unicast IP.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2GWAHkJLOKz7tR9rIgwfgG/5b7e68b8e02942697d7de1fbf6d74b0e/image5-16.png" />
            
            </figure>
    <div>
      <h3>Segmenting traffic based on egress IP</h3>
      <a href="#segmenting-traffic-based-on-egress-ip">
        
      </a>
    </div>
    <p>Originally connections sourced by Cloudflare were mostly HTTP fetches going to origin servers on the Internet. As our product line grew, so did the variety of traffic. The most notable example is <a href="/1111-warp-better-vpn/">our WARP app</a>. For WARP, our servers operate a forward proxy, and handle the traffic sourced by end-user devices. It's done without the same degree of intermediation as in our <a href="https://www.cloudflare.com/application-services/products/cdn/">CDN product</a>. This creates a problem. Third party servers on the Internet — like the origin servers — must be able to distinguish between connections coming from Cloudflare services and our WARP users. Such traffic segmentation is traditionally done by using different IP ranges for different traffic types (although recently we introduced more robust techniques like <a href="https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull/">Authenticated Origin Pulls</a>).</p><p>To work around the trusted vs untrusted traffic pool differentiation problem, we added an untrusted WARP IP address to each of our servers:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2hudtFCXBWUe1aRFIfcH7s/47bca3701568a8562029e41334d79692/image4-30.png" />
            
            </figure>
    <div>
      <h3>Country tagged egress IP addresses</h3>
      <a href="#country-tagged-egress-ip-addresses">
        
      </a>
    </div>
    <p>It quickly became apparent that trusted vs untrusted weren't the only tags needed. For WARP service we also need country tags. For example, United Kingdom based WARP users expect the bbc.com website to just work. However, the BBC restricts many of its services to people just in the UK.</p><p>It does this by <i>geofencing</i> — using a database mapping public IP addresses to countries, and allowing only the UK ones. Geofencing is widespread on today's Internet. To avoid geofencing issues, we need to choose specific egress addresses tagged with an appropriate country, depending on WARP user location. Like many other parties on the Internet, we tag our egress IP space with country codes and publish it as a geofeed (like <a href="https://mask-api.icloud.com/egress-ip-ranges.csv">this one</a>). Notice, the published geofeed is just data. The fact that an IP is tagged as say UK does not mean it is served from the UK, it just means the operator wants it to be geolocated to the UK. Like many things on the Internet, it is based on trust.</p><p>Notice, at this point we have three independent geographical tags:</p><ul><li><p>the country tag of the WARP user - the eyeball connecting IP</p></li><li><p>the location of the data center the eyeball connected to</p></li><li><p>the country tag of the egressing IP</p></li></ul><p>For best service, we want to choose the egressing IP so that its country tag matches the country from the eyeball IP. But egressing from a specific country tagged IP is challenging: our data centers serve users from all over the world, potentially from many countries! Remember: due to anycast we don't directly control the ingress routing. Internet geography doesn’t always match physical geography. For example our London data center receives traffic not only from users in the United Kingdom, but also from Ireland, and Saudi Arabia. As a result, our servers in London need many WARP egress addresses associated with many countries:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6rcN3OCsVAvpWBiER4JHgI/6edbc6ec71af73c39d13c52e8e50b4e0/image2-52.png" />
            
            </figure><p>Can you see where this is going? The problem space just explodes! Instead of having one or two egress IP addresses for each server, now we require dozens, and <a href="/amazon-2bn-ipv4-tax-how-avoid-paying">IPv4 addresses aren't cheap</a>. With this design, we need many addresses per server, and we operate thousands of servers. This architecture becomes very expensive.</p>
    <div>
      <h3>Is anycast a problem?</h3>
      <a href="#is-anycast-a-problem">
        
      </a>
    </div>
    <p>Let me recap: with anycast ingress we don't control which data center the user is routed to. Therefore, each of our data centers must be able to egress from an address with any conceivable tag. Inside the data center we also don't control which server the connection is routed to. There are potentially many tags, many data centers, and many servers inside a data center.</p><p>Maybe the problem is the ingress architecture? Perhaps it's better to use a traditional networking design where a specific eyeball is routed with <a href="https://www.cloudflare.com/learning/dns/what-is-dns/">DNS</a> to a specific data center, or even a server?</p><p>That's one way of thinking, but we decided against it. We like our anycast on ingress. It brings us many advantages:</p><ul><li><p><b>Performance</b>: with anycast, by definition, the eyeball is routed to the closest (by BGP metrics) data center. This is usually the fastest data center for a given user.</p></li><li><p><b>Automatic failover</b>: if one of our data centers becomes unavailable, the traffic will be instantly, automatically re-routed to the next best place.</p></li><li><p><b>DDoS resilience</b>: during a <a href="https://www.cloudflare.com/learning/ddos/what-is-a-ddos-attack/">denial of service attack</a> or a traffic spike, the load is automatically balanced across many data centers, significantly reducing the impact.</p></li><li><p><b>Uniform software</b>: The functionality of every data center and of every server inside a data center is identical. We use the same software stack on all the servers around the world. Each machine can perform any action, for any product. This enables easy debugging and good scalability.</p></li></ul><p>For these reasons we'd like to keep the anycast on ingress. We decided to solve the issue of egress address cardinality in some other way.</p>
    <div>
      <h3>Solving a million dollar problem</h3>
      <a href="#solving-a-million-dollar-problem">
        
      </a>
    </div>
    <p>Out of the thousands of servers we operate, every single one should be able to use an egress IP with any of the possible tags. It's easiest to explain our solution by first showing two extreme designs.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1UoCyD5rIsCDc6nAMY1jvp/646cd025de3707b60b205682f3b140c8/image6-10.png" />
            
            </figure><p><b>Each server owns all the needed IPs:</b> each server has all the specialized egress IPs with the needed tags.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3s0xwHrfjPQpusPeq9HTtX/3338238e28e89abcaa5b4fc3eff2cc09/image12-1.png" />
            
            </figure><p><b>One server owns the needed IP:</b> a specialized egress IP with a specific tag lives in one place, other servers forward traffic to it.</p><p>Both options have pros and cons:</p><table>
<thead>
  <tr>
    <th>Specialized IP on every server</th>
    <th>Specialized IP on one server</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Super expensive $$$, every server needs many IP addresses.</td>
    <td>Cheap $, only one specialized IP needed for a tag.</td>
  </tr>
  <tr>
    <td>Egress always local - fast</td>
    <td>Egress almost always forwarded - slow</td>
  </tr>
  <tr>
    <td>Excellent reliability - every server is independent</td>
    <td>Poor reliability - introduced chokepoints</td>
  </tr>
</tbody>
</table>
    <div>
      <h3>There's a third way</h3>
      <a href="#theres-a-third-way">
        
      </a>
    </div>
    <p>We've been thinking hard about this problem. Frankly, the first extreme option of having every needed IP available locally on every Cloudflare server is not totally unworkable. This is, roughly, what we were able to pull off for IPv6. With IPv6, access to the large needed IP space is not a problem.</p><p>However, in IPv4 neither option is acceptable. The first offers fast and reliable egress, but requires great cost — the IPv4 addresses needed are expensive. The second option uses the smallest possible IP space, so it's cheap, but compromises on performance and reliability.</p><p>The solution we devised is a compromise between the extremes. The rough idea is to change the assignment unit. Instead of assigning one /32 IPv4 address for each server, we devised a method of assigning a /32 IP per data center, and then sharing it among physical servers.</p><table>
<thead>
  <tr>
    <th>Specialized IP on every server</th>
    <th>Specialized IP per data center</th>
    <th>Specialized IP on one server</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Super expensive $$$</td>
    <td>Reasonably priced $$</td>
    <td>Cheap $</td>
  </tr>
  <tr>
    <td>Egress always local - fast</td>
    <td>Egress always local - fast</td>
    <td>Egress almost always forwarded - slow</td>
  </tr>
  <tr>
    <td>Excellent reliability - every server is independent</td>
    <td>Excellent reliability - every server is independent</td>
    <td>Poor reliability - many choke points</td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Sharing an IP inside data center</h3>
      <a href="#sharing-an-ip-inside-data-center">
        
      </a>
    </div>
    <p>The idea of sharing an IP among servers is not new. Traditionally this can be achieved by Source-NAT on a router. Sadly, the sheer number of egress IP's we need and the size of our operation, prevents us from relying on stateful firewall / NAT at the router level. We also dislike shared state, so we're not fans of distributed NAT installations.</p><p>What we chose instead, is splitting an egress IP across servers by <b>a port range</b>. For a given egress IP, each server owns a small portion of available source ports - a port slice.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6ruhT8POdI4Vd3yDd4WIrh/5204f34fbe65306902cb0b12216cedd4/image1-68.png" />
            
            </figure><p>When return packets arrive from the Internet, we have to route them back to the correct machine. For this task we've customized "Unimog" - our L4 XDP-based load balancer - ("<a href="/unimog-cloudflares-edge-load-balancer/">Unimog, Cloudflare's load balancer (2020)</a>") and it's working flawlessly.</p><p>With a port slice of say 2,048 ports, we can share one IP among 31 servers. However, there is always a possibility of running out of ports. To address this, we've worked hard to be able to reuse the egress ports efficiently. See the "<a href="/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/">How to stop running out of ports (2022)</a>", "<a href="https://lpc.events/event/16/contributions/1349/">How to share IPv4 addresses (2022)</a>" and our <a href="https://cloudflare.tv/event/oZKxMJg4">Cloudflare.TV segment</a>.</p><p>This is pretty much it. Each server is aware which IP addresses and port slices it owns. For inbound routing Unimog inspects the ports and dispatches the packets to appropriate machines.</p>
    <div>
      <h3>Sharing a subnet between data centers</h3>
      <a href="#sharing-a-subnet-between-data-centers">
        
      </a>
    </div>
    <p>This is not the end of the story though, we haven't discussed how we can route a single /32 address into a datacenter. Traditionally, in the public Internet, it's only possible to route subnets with granularity of /24 or 256 IP addresses. In our case this would lead to great waste of IP space.</p><p>To solve this problem and improve the utilization of our IP space, we deployed our egress ranges as... <b>anycast</b>! With that in place, we customized Unimog and taught it to forward the packets over our <a href="/cloudflare-backbone-internet-fast-lane/">backbone network</a> to the right data center. Unimog maintains a database like this:</p>
            <pre><code>198.51.100.1 - forward to LHR
198.51.100.2 - forward to CDG
198.51.100.3 - forward to MAN
...</code></pre>
            <p>With this design, it doesn't matter to which data center return packets are delivered. Unimog can always fix it and forward the data to the right place. Basically, while at the <a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/">BGP layer</a> we are using anycast, due to our design, semantically an IP identifies a datacenter and an IP and port range identify a specific machine. It behaves almost like a unicast.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1aQ9FLJSpyr3OjcEynnyse/0274312eac4adaa6f391e7e48d3d6e3c/image7-6.png" />
            
            </figure><p>We call this technology stack "<b>soft-unicast</b>" and it feels magical. It's like we did unicast in software over anycast in the BGP layer.</p>
    <div>
      <h3>Soft-unicast is indistinguishable from magic</h3>
      <a href="#soft-unicast-is-indistinguishable-from-magic">
        
      </a>
    </div>
    <p>With this setup we can achieve significant benefits:</p><ul><li><p>We are able to share a /32 egress IP amongst <b>many servers</b>.</p></li><li><p>We can spread a single subnet across <b>many data centers</b>, and change it easily on the fly. This allows us to fully use our egress IPv4 ranges.</p></li><li><p>We can <b>group similar IP addresses</b> together. For example, all the IP addresses tagged with the "UK" tag might form a single continuous range. This reduces the size of the published geofeed.</p></li><li><p>It's easy for us to <b>onboard new egress IP ranges</b>, like customer IP's. This is useful for some of our products, like <a href="https://www.cloudflare.com/products/zero-trust/">Cloudflare Zero Trust</a>.</p></li></ul><p>All this is done at sensible cost, at no loss to performance and reliability:</p><ul><li><p>Typically, the user is able to egress directly from the closest datacenter, providing the <b>best possible performance</b>.</p></li><li><p>Depending on the actual needs we can allocate or release the IP addresses. This gives us <b>flexibility with the IP</b> cost management, we don't need to overspend upfront.</p></li><li><p>Since we operate multiple egress IP addresses in different locations, the <b>reliability is not compromised</b>.</p></li></ul>
    <div>
      <h3>The true location of our IP addresses is: “the cloud”</h3>
      <a href="#the-true-location-of-our-ip-addresses-is-the-cloud">
        
      </a>
    </div>
    <p>While soft-unicast allows us to gain great efficiency, we've hit some issues. Sometimes we get a question "Where does this IP physically exist?". But it doesn't have an answer! Our egress IPs don't exist physically anywhere. From a BGP standpoint our egress ranges are anycast, so they live everywhere. Logically each address is used in one data center at a time, but we can move it around on demand.</p>
    <div>
      <h3>Content Delivery Networks misdirect users</h3>
      <a href="#content-delivery-networks-misdirect-users">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5sCk5BkrFFweDjmy5zQnHs/058bef00f049ab0445b59d70a422f5d0/image3-43.png" />
            
            </figure><p>As another example of problems, here's one issue we've hit with third party CDNs. As we mentioned before, there are three country tags in our pipeline:</p><ul><li><p>The country tag of the IP eyeball is connecting from.</p></li><li><p>The location of our data center.</p></li><li><p>The country tag of the IP addresses we chose for the egress connections.</p></li></ul><p>The fact that our egress address is tagged as "UK" doesn't always mean it actually is being used in the UK. We’ve had cases when a UK-tagged WARP user, due to the maintenance of our LHR data center, was routed to Paris. A popular <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">CDN</a> performed a reverse-lookup of our egress IP, found it tagged as "UK", and directed the user to a London CDN server. This is generally OK... but we actually egressed from Paris at the time. This user ended up routing packets from their home in the UK, to Paris, and back to the UK. This is bad for performance.</p><p>We address this issue by performing DNS requests in the egressing data center. For DNS we use IP addresses tagged with the location of the <b>data center</b>, not the intended geolocation for the user. This generally fixes the problem, but sadly, there are still some exceptions.</p>
    <div>
      <h3>The future is here</h3>
      <a href="#the-future-is-here">
        
      </a>
    </div>
    <p>Our 2021 experiments with <a href="/addressing-agility/">Addressing Agility</a> proved we have plenty of opportunity to innovate with the addressing of the ingress. Soft-unicast shows us we can achieve great flexibility and density on the egress side.</p><p>With each new product, the number of tags we need on the egress grows - from traffic trustworthiness, product category to geolocation. As the pool of usable IPv4 addresses shrinks, we can be sure there will be more innovation in the space. Soft-unicast is our solution, but for sure it's not our last development.</p><p>For now though, it seems like we're moving away from traditional unicast. Our egress IP's really don't exist in a fixed place anymore, and some of our servers don't even own a true unicast IP nowadays.</p> ]]></content:encoded>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">60l7qhQ3DKYiHtI3TduJSc</guid>
            <dc:creator>Marek Majkowski</dc:creator>
        </item>
        <item>
            <title><![CDATA[Why BGP communities are better than AS-path prepends]]></title>
            <link>https://blog.cloudflare.com/prepends-considered-harmful/</link>
            <pubDate>Thu, 24 Nov 2022 17:31:47 GMT</pubDate>
            <description><![CDATA[ Routing on the Internet follows a few basic principles. Unfortunately not everything on the Internet is created equal, and prepending can do more harm than good. In this blog post we’ll talk about the problems that prepending aims to solve, and some alternative solutions ]]></description>
            <content:encoded><![CDATA[ <p><i></i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2E41RLSZSaS34QDzUqX1Rd/7ebce0374cd5f67f333eaf954e6f1445/image7-9.png" />
            
            </figure><p>The Internet, in its purest form, is a loosely connected graph of independent networks (also called <a href="https://www.cloudflare.com/en-gb/learning/network-layer/what-is-an-autonomous-system/">Autonomous Systems</a> (AS for short)). These networks use a signaling protocol called <a href="https://www.cloudflare.com/en-gb/learning/security/glossary/what-is-bgp/">BGP</a> (Border Gateway Protocol) to inform their neighbors (also known as peers) about the reachability of IP prefixes (a group of IP addresses) in and through their network. Part of this exchange contains useful metadata about the IP prefix that are used to inform network routing decisions. One example of the metadata is the full AS-path, which consists of the different autonomous systems an IP packet needs to pass through to reach its destination.</p><p>As we all want our packets to get to their destination as fast as possible, selecting the shortest AS-path for a given prefix is a good idea. This is where something called prepending comes into play.</p>
    <div>
      <h2>Routing on the Internet, a primer</h2>
      <a href="#routing-on-the-internet-a-primer">
        
      </a>
    </div>
    <p>Let's briefly talk about how the Internet works at its most fundamental level, before we dive into some nitty-gritty details.</p><p>The Internet is, at its core, a massively interconnected network of thousands of networks. Each network owns two things that are critical:</p><p>1. An Autonomous System Number (ASN): a 32-bit integer that uniquely identifies a network. For example, one of the Cloudflare ASNs (we have multiple) is 13335.</p><p>2. IP prefixes: An IP prefix is a range of IP addresses, bundled together in powers of two: In the IPv4 space, two addresses form a /31 prefix, four form a /30, and so on, all the way up to /0, which is shorthand for “all IPv4 prefixes''. The same applies for IPv6  but instead of aggregating 32 bits at most, you can aggregate up to 128 bits. The figure below shows this relationship between IP prefixes, in reverse -- a /24 contains two /25s that contains two /26s, and so on.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5XUwaT0EJLzfHUwkpm7aN2/47a248cc3292ae8a970423c8f3de9f5b/image9-6.png" />
            
            </figure><p>To communicate on the Internet, you must be able to reach your destination, and that’s where routing protocols come into play. They enable each node on the Internet to know where to send your message (and for the receiver to send a message back).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6RzDynXtAzTFAAeSRNF7Qz/f3297d7747eb351a77dfb3da7461944a/image5-21.png" />
            
            </figure><p>As mentioned earlier, these destinations are identified by IP addresses, and contiguous ranges of IP addresses are expressed as IP prefixes. We use IP prefixes for routing as an efficiency optimization: Keeping track of where to go for four billion (2<sup>32</sup>) IP addresses in IPv4 would be incredibly complex, and require a lot of resources. Sticking to prefixes reduces that number down to about one million instead.</p><p>Now recall that Autonomous Systems are independently operated and controlled. In the Internet’s network of networks, how do I tell Source A in some other network that there is an available path to get to Destination B in (or through) my network? In comes BGP! BGP is the Border Gateway Protocol, and it is used to signal reachability information. Signal messages generated by the source ASN are referred to as ‘announcements’ because they declare to the Internet that IP addresses in the prefix are online and reachable.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/cudmPAIkxVZr5tOuSqQdm/f096de61cdebaa7c9427343be70cb0ff/image4-33.png" />
            
            </figure><p>Have a look at the figure above. Source A should now know how to get to Destination B through 2 different networks!</p><p>This is what an actual BGP message would look like:</p>
            <pre><code>BGP Message
    Type: UPDATE Message
    Path Attributes:
        Path Attribute - Origin: IGP
        Path Attribute - AS_PATH: 64500 64496
        Path Attribute - NEXT_HOP: 198.51.100.1
        Path Attribute - COMMUNITIES: 64500:13335
        Path Attribute - Multi Exit Discriminator (MED): 100
    Network Layer Reachability Information (NLRI):
        192.0.2.0/24</code></pre>
            <p>As you can see, BGP messages contain more than just the IP prefix (the NLRI bit) and the path, but also a bunch of other metadata that provides additional information about the path. Other fields include communities (more on that later), as well as MED, or origin code. MED is a suggestion to other directly connected networks on which path should be taken if multiple options are available, and the lowest value wins. The origin code can be one of three values: IGP, EGP or Incomplete. IGP will be set if you originate the prefix through BGP, EGP is no longer used (it’s an ancient routing protocol), and Incomplete is set when you distribute a prefix into BGP from another routing protocol (like IS-IS or OSPF).</p><p>Now that source A knows how to get to Destination B through two different networks, let's talk about traffic engineering!</p>
    <div>
      <h2>Traffic engineering</h2>
      <a href="#traffic-engineering">
        
      </a>
    </div>
    <p>Traffic engineering is a critical part of the day to day management of any network. Just like in the physical world, detours can be put in place by operators to optimize the traffic flows into (inbound) and out of (outbound) their network. Outbound traffic engineering is significantly easier than inbound traffic engineering because operators can choose from neighboring networks, even prioritize some traffic over others. In contrast, inbound traffic engineering requires influencing a network that is operated by someone else entirely. The autonomy and self-governance of a network is paramount, so operators use available tools to inform or shape inbound packet flows from other networks. The understanding and use of those tools is complex, and can be a challenge.</p><p>The available set of traffic engineering tools, both in- and outbound, rely on manipulating attributes (metadata) of a given route. As we’re talking about traffic engineering between independent networks, we’ll be manipulating the attributes of an EBGP-learned route. BGP can be split into two categories:</p><ol><li><p>EBGP: BGP communication between two different ASNs</p></li><li><p>IBGP: BGP communication within the same ASN.</p></li></ol><p>While the protocol is the same, certain attributes can be exchanged on an IBGP session that aren’t exchanged on an EBGP session. One of those is local-preference. More on that in a moment.</p>
    <div>
      <h3>BGP best path selection</h3>
      <a href="#bgp-best-path-selection">
        
      </a>
    </div>
    <p>When a network is connected to multiple other networks and service providers, it can receive path information to the same IP prefix from many of those networks, each with slightly different attributes. It is then up to the receiving network of that information to use a BGP best path selection algorithm to pick the “best” prefix (and route), and use this to forward IP traffic. I’ve put “best” in quotation marks, as best is a subjective requirement. “Best” is frequently the shortest, but what can be best for my network might not be the best outcome for another network.</p><p>BGP will consider multiple prefix attributes when filtering through the received options. However, rather than combine all those attributes into a single selection criteria, BGP best path selection uses the attributes in tiers -- at any tier, if the available attributes are sufficient to choose the best path, then the algorithm terminates with that choice.</p><p>The BGP best path selection algorithm is extensive, containing 15 discrete steps to select the best available path for a given prefix. Given the numerous steps, it’s in the interest of the network to decide the best path as early as possible. The first four steps are most used and influential, and are depicted in the figure below as sieves.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/28iOxj73xffT9imICxgTTI/504e3ea0c7767d8acae1ee0ca0b64c4d/image2-55.png" />
            
            </figure><p>Picking the shortest path possible is usually a good idea, which is why “AS-path length” is a step executed early on in the algorithm. However, looking at the figure above, “AS-path length” appears second, despite being the attribute to find the shortest path. So let’s talk about the first step: local preference.</p><p><b>Local preference</b>Local preference is an operator favorite because it allows them to handpick a route+path combination of their choice. It’s the first attribute in the algorithm because it is unique for any given route+neighbor+AS-path combination.</p><p>A network sets the local preference on import of a route (having learned about the route from a neighbor network). Being a non-transitive property, meaning that it’s an attribute that is never sent in an EBGP message to other networks. This intrinsically means, for example, that the operator of AS 64496 can’t set the local preference of routes to their own (or transiting) IP prefixes inside neighboring AS 64511. The inability to do so is partially why inbound traffic engineering through EBGP is so difficult.</p><p><b>Prepending artificially increases AS-path length</b>Since no network is able to directly set the local preference for a prefix inside another network, the first opportunity to influence other networks’ choices is modifying the AS-path. If the next hops are valid, and the local preference for all the different paths for a given route are the same, modifying the AS-path is an obvious option to change the path traffic will take towards your network. In a BGP message, prepending looks like this:</p><p>BEFORE:</p>
            <pre><code>BGP Message
    Type: UPDATE Message
    Path Attributes:
        Path Attribute - Origin: IGP
        Path Attribute - AS_PATH: 64500 64496
        Path Attribute - NEXT_HOP: 198.51.100.1
        Path Attribute - COMMUNITIES: 64500:13335
        Path Attribute - Multi Exit Discriminator (MED): 100
    Network Layer Reachability Information (NLRI):
        192.0.2.0/24</code></pre>
            <p>AFTER:</p>
            <pre><code>BGP Message
    Type: UPDATE Message
    Path Attributes:
        Path Attribute - Origin: IGP
        Path Attribute - AS_PATH: 64500 64496 64496
        Path Attribute - NEXT_HOP: 198.51.100.1
        Path Attribute - COMMUNITIES: 64500:13335
        Path Attribute - Multi Exit Discriminator (MED): 100
    Network Layer Reachability Information (NLRI):
        192.0.2.0/24</code></pre>
            <p>Specifically, operators can do AS-path prepending. When doing AS-path prepending, an operator adds additional autonomous systems to the path (usually the operator uses their own AS, but that’s not enforced in the protocol). This way, an AS-path can go from a length of 1 to a length of 255. As the length has now increased dramatically, that specific path for the route will not be chosen. By changing the AS-path advertised to different peers, an operator can control the traffic flows coming into their network.</p><p>Unfortunately, prepending has a catch: To be the deciding factor, all the other attributes need to be equal. This is rarely true, especially in large networks that are able to choose from many possible routes to a destination.</p>
    <div>
      <h2>Business Policy Engine</h2>
      <a href="#business-policy-engine">
        
      </a>
    </div>
    <p>BGP is colloquially also referred to as a Business Policy Engine: it does <b>not</b> select the best path from a performance point of view; instead, and more often than not, it will select the best path from a <i>business</i> point of view. The business criteria could be anything from investment (port) efficiency to increased revenue, and more. This may sound strange but, believe it or not, this is what BGP is designed to do! The power (and complexity) of BGP is that it enables a network operator to make choices according to the operator’s needs, contracts, and policies, many of which cannot be reflected by conventional notions of engineering performance.</p>
    <div>
      <h3>Different local preferences</h3>
      <a href="#different-local-preferences">
        
      </a>
    </div>
    <p>A lot of networks (including Cloudflare) assign a local preference depending on the type of connection used to send us the routes. A higher value is a higher preference. For example, routes learned from transit network connections will get a lower local preference of 100 because they are the most costly to use; backbone-learned routes will be 150, Internet exchange (IX) routes get 200, and lastly private interconnect (PNI) routes get 250. This means that for egress (outbound) traffic, the Cloudflare network, by default, will prefer a PNI-learned route, even if a shorter AS-path is available through an IX or transit neighbor.</p><p>Part of the reason a PNI is preferred over an IX is reliability, because there is no third-party switching platform involved that is out of our control, which is important because we operate on the assumption that all hardware can and will eventually break. Another part of the reason is for port efficiency reasons. Here, efficiency is defined by cost per megabit transferred on each port. Roughly speaking, the cost is calculated by:</p><p><code>((cost_of_switch / port_count) + transceiver_cost)</code></p><p>which is combined with the cross-connect cost (might be monthly recurring (MRC), or a one-time fee). PNI is preferable because it helps to optimize value by reducing the overall cost per megabit transferred, because the unit price decreases with higher utilization of the port.</p><p>This reasoning is similar for a lot of other networks, and is very prevalent in transit networks. BGP is at least as much about cost and business policy, as it is about performance.</p>
    <div>
      <h3>Transit local preference</h3>
      <a href="#transit-local-preference">
        
      </a>
    </div>
    <p>For simplicity, when referring to transits, I mean the <a href="https://en.wikipedia.org/wiki/Tier_1_network">traditional tier-1 transit networks</a>. Due to the nature of these networks, they have two distinct sets of network peers:</p><p>1. Customers (like Cloudflare)2. Settlement-free peers (like other tier-1 networks)</p><p>In normal circumstances, transit customers will get a higher local preference assigned than the local preference used for their settlement-free peers. This means that, no matter how much you prepend a prefix, if traffic enters that transit network, traffic will <b>always</b> land on your interconnection with that transit network, it will not be offloaded to another peer.</p><p>A prepend can still be used if you want to switch/offload traffic from a single link with one transit if you have multiple distinguished links with them, or if the source of traffic is multihomed behind multiple transits (and they don’t have their own local preference playbook preferring one transit over another). But inbound traffic engineering traffic away from one transit port to another through AS-path prepending has significant diminishing returns: once you’re past three prepends, it’s unlikely to change much, if anything, at that point.</p><p><b>Example</b></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/8QW8idtVhFb2jtY64uTLf/696a61224544698eb35a8e7ae20f8a22/image8-6.png" />
            
            </figure><p>In the above scenario, no matter the adjustment Cloudflare makes in its AS-path towards AS 64496, the traffic will keep flowing through the Transit B &lt;&gt; Cloudflare interconnection, even though the path Origin A → Transit B → Transit A → Cloudflare is shorter from an AS-path point of view.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2uNwYLR8BdzCHVTzISwgtk/581ea233f8058f998bf00dfaa44ca3e3/image6-12.png" />
            
            </figure><p>In this scenario, not a lot has changed, but Origin A is now multi-homed behind the two transit providers. In this case, the AS-path prepending was effective, as the paths seen on the Origin A side are both the prepended and non-prepended path. As long as Origin A is not doing any egress traffic engineering, and is treating both transit networks equally, then the path chosen will be Origin A → Transit A → Cloudflare.</p>
    <div>
      <h3>Community-based traffic engineering</h3>
      <a href="#community-based-traffic-engineering">
        
      </a>
    </div>
    <p>So we have now identified a pretty critical problem within the Internet ecosystem for operators: with the tools mentioned above, it’s not always (some might even say outright impossible) possible to accurately dictate paths traffic can ingress your own network, reducing the control an autonomous system has over its own network. Fortunately, there is a solution for this problem: community-based local preference.</p><p>Some transit providers allow their customers to influence the local preference in the transit network through the use of BGP communities. BGP communities are an optional transitive attribute for a route advertisement. The communities can be informative (“I learned this prefix in Rome”), but they can also be used to trigger actions on the receiving side. For example, Cogent publishes the following action communities:</p><table>
<thead>
  <tr>
    <th>Community</th>
    <th>Local preference</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>174:10</td>
    <td>10</td>
  </tr>
  <tr>
    <td>174:70</td>
    <td>70</td>
  </tr>
  <tr>
    <td>174:120</td>
    <td>120</td>
  </tr>
  <tr>
    <td>174:125</td>
    <td>125</td>
  </tr>
  <tr>
    <td>174:135</td>
    <td>135</td>
  </tr>
  <tr>
    <td>174:140</td>
    <td>140</td>
  </tr>
</tbody>
</table><p>When you know that Cogent uses the following default local preferences in their network:</p><p>Peers → Local preference 100Customers → Local preference 130</p><p>It’s easy to see how we could use the communities provided to change the route used. It’s important to note though that, as we can’t set the local preference of a route to 100 (or 130), AS-path prepending remains largely irrelevant, as the local preference won’t ever be the same.</p><p>Take for example the following configuration:</p>
            <pre><code>term ADV-SITELOCAL {
    from {
        prefix-list SITE-LOCAL;
        route-type internal;
    }
    then {
        as-path-prepend "13335 13335";
        accept;
    }
}</code></pre>
            
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2QJPzju5z4aHCOTxSEAO9y/21cf93066b2a67a48f530af5934c58d3/image1-71.png" />
            
            </figure><p>We’re prepending the Cloudflare ASN two times, resulting in a total AS-path of three, yet we were still seeing a lot (too much) traffic coming in on our Cogent link. At that point, an engineer could add another prepend, but for a well-connected network as Cloudflare, if two prepends didn’t do much, or three, then four or five isn’t going to do much either. Instead, we can leverage the Cogent communities documented above to change the routing within Cogent:</p>
            <pre><code>term ADV-SITELOCAL {
    from {
        prefix-list SITE-LOCAL;
        route-type internal;
    }
    then {
        community add COGENT_LPREF70;
        accept;
    }
}</code></pre>
            <p>The above configuration changes the traffic flow to this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1hJxj0OColxsHeP06JAfBb/8fa01b2f92b44de8b129b761dccc9acf/image3-47.png" />
            
            </figure><p>Which is exactly what we wanted!</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>AS-path prepending is still useful, and has its use as part of the toolchain for operators to do traffic engineering, but should be used sparingly. <a href="https://ripe79.ripe.net/presentations/64-prepending_madory2.pdf">Excessive prepending opens a network up to wider spread route hijacks</a>, which should be avoided at all costs. As such, using community-based ingress traffic engineering is highly preferred (and recommended). In cases where communities aren’t available (or not available to steer customer traffic), prepends can be applied, but I encourage operators to actively monitor their effects, and roll them back if ineffective.</p><p>As a side-note, P Marcos et al. have published an interesting paper on AS-path prepending, and go into some trends seen in relation to prepending, I highly recommend giving it a read: <a href="https://www.caida.org/catalog/papers/2020_aspath_prepending/aspath_prepending.pdf">https://www.caida.org/catalog/papers/2020_aspath_prepending/aspath_prepending.pdf</a></p> ]]></content:encoded>
            <category><![CDATA[Routing]]></category>
            <category><![CDATA[BGP]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">7xqrew8H7IM1awzPwN3MOw</guid>
            <dc:creator>Tom Strickx</dc:creator>
        </item>
    </channel>
</rss>