Technical writing
Mapping censorship infrastructure: identifying filtering gateways, DPI vendor signatures, and blocking architecture from network signals
The Voidly dataset classifies interference by type — DNS tampering, TLS interference, HTTP blocking, TCP RST injection, throttling — and that classification is what drives the anomaly detector and the public incident feed. But the underlying question researchers and policy analysts most often ask is different: who is doing the blocking, and with what equipment? A DNS NXDOMAIN injection in Russia and a DNS NXDOMAIN injection in Turkey both look identical at the interference-type level, but one originates from a TSPU appliance at a backbone IXP running state-mandated software, and the other originates from an ISP-level transparent resolver operating under a court order. That distinction matters for understanding the political economy of censorship, for tracking vendor accountability, and for designing circumvention strategies that account for the actual filtering architecture.
This article covers how Voidly uses timing signals, packet-level patterns, block page fingerprints, and OSINT cross-referencing to characterize the specific filtering infrastructure behind each interference event. This is not attribution in the legal sense — attributing state-sponsored network interference to a government actor with legal evidentiary weight requires direct access to infrastructure or court-admissible forensic methods that network measurement cannot provide. What Voidly offers is infrastructure characterization: matching observed network behavior against known signatures of specific hardware and software systems. The distinction matters for methodological transparency, and the dataset's censorship_infrastructure field is documented with that limitation explicitly.
Blocking architecture taxonomy
Before identifying specific vendors, it is useful to establish which layer of the network stack the blocking operates at. Different layers require different detection methods, leave different observables in the packet trace, and correspond to different categories of filtering equipment. Voidly classifies blocking events into four architectural layers.
Layer 3: BGP and routing-level blocking
The coarsest form of censorship: entire ASNs or IP prefixes are withdrawn from BGP routing tables or null-routed, making all traffic to those prefixes unreachable regardless of destination port, protocol, or domain. This affects every application simultaneously and produces no application-layer observable — the IP is simply unreachable. The signature is a BGP prefix withdrawal visible in BGP route collector data (RouteViews, RIPE RIS) combined with simultaneous loss of ICMP reachability to addresses within the withdrawn prefix. Ethiopia's 2020 election internet shutdowns and Sudan's 2019 protest-related shutdowns are documented examples where entire ASNs went dark in BGP and the ICMP loss confirmed it was not a routing misconfiguration.
Layer 4: TCP RST injection and IP null-routing
TCP-layer blocking targets specific IP addresses rather than entire prefixes, and is implemented either by null-routing at the router level or by injecting TCP RST packets from a middlebox on the backbone. The signature of RST injection is a RST packet arriving at the probe unusually fast — typically under 15 ms from the SYN — from a hop that is not the actual destination server. RST injection is faster than a legitimate server response because the blocking device synthesizes the RST locally without forwarding the SYN to the destination. The RST's TTL at the probe, analyzed against expected initial TTLs, reveals how many hops away the injection device sits on the backbone.
Layer 7 — DNS: resolver-level tampering
DNS blocking operates at the recursive resolver that the probe uses for name resolution. The resolver returns either NXDOMAIN (the domain does not exist) or a bogon IP (a non-routable or government-controlled address) in place of the correct answer. The signature is unambiguous when detectable: the probe's ISP resolver returns a wrong answer, while a public resolver such as 8.8.8.8 queried over an out-of-band channel returns the correct IP. The dual-resolver architecture that Voidly probes use for every DNS measurement makes this the most reliably detected blocking type in the dataset.
Layer 7 — HTTP: transparent proxy interception
HTTP blocking intercepts unencrypted HTTP traffic at a transparent proxy, which terminates the connection and returns a block page or a redirect rather than forwarding the request to the origin server. The signature is an HTTP response body that does not match the expected content — typically a block page with government or ISP branding — paired with either a 403, 451, or 200 status code (block pages occasionally return 200 to avoid browser error screens). HTTPS traffic at this layer passes through to the TLS measurement, which handles the blocking at the handshake level if SNI-based filtering is in place.
| Blocking layer | Detection method | Example countries | Approximate prevalence in Voidly dataset |
|---|---|---|---|
| L3 BGP/routing | BGP prefix withdrawal + ICMP unreachability | Ethiopia, Sudan, Myanmar | 3% |
| L4 TCP RST/null-route | Fast RST (< 15 ms) from unexpected TTL hop; SYN timeout | China, Iran, Russia | 18% |
| L7 DNS | Dual-resolver comparison; NXDOMAIN or bogon IP from ISP resolver | Turkey, Indonesia, Pakistan | 41% |
| L7 HTTP transparent proxy | Block page body in HTTP response; 403/451 status or body hash match | Turkey, UK, Australia | 38% |
DPI vendor signatures
Within each blocking layer, the specific hardware and software vendor leaves detectable fingerprints in timing patterns, packet fields, and block page content. Voidly has identified characteristic signatures from several commercially deployed or state-built deep packet inspection systems currently active in the measurement data.
TSPU (Russia)
Russia's Technical Means for Countering Threats (Tekhnicheskoe Sredstvo Protivodeystviya Ugrozam, TSPU) is the DPI infrastructure mandated under Federal Law 149-FZ and deployed at backbone IXPs from 2021 onward. Its characteristic signatures are exceptionally clean because the devices operate at the backbone and respond to probe traffic without network-path variability softening the timing signals.
RST injection arrives at the probe in under 3 ms from the moment the ClientHello is sent — faster than any legitimate server round-trip, and faster than the probe's own TCP stack would normally process a local RST. The TCP sequence numbers in the injected RST match the probe's SYN sequence number exactly, confirming the RST was synthesized by a stateful device that captured the original SYN. In throttling mode (used against YouTube and Twitter during 2023), the TSPU reduces body transfer rate to a precisely configured value — for example, 128 KB/s — with no burst allowed. Throttled flows show a flat transfer rate profile that does not vary with congestion window changes, which is characteristic of token-bucket enforcement by an external policer rather than TCP congestion control.
ARRS (Iran)
Iran's filtering infrastructure, associated with the Islamic Republic's Advanced Regulatory and Routing System (ARRS) operated through the Telecommunication Infrastructure Company (TIC), produces NXDOMAIN injection from specific known resolver IPs. Voidly probes in Iran have documented the internal test page served by resolver address 10.10.34.35 — an RFC 1918 address that appears in NXDOMAIN responses and is a documented artifact of the Iranian filtering infrastructure used internally to verify that the block is active. Block pages served by ARRS carry specific HTML signatures including Farsi-language government messaging that Voidly's block page fingerprint library catalogs in 23 distinct variants corresponding to different censorship categories (political, moral, security).
GFW (China)
China's Great Firewall is the longest-running and most thoroughly documented DPI censorship system in the measurement literature. It operates multiple concurrent techniques simultaneously on many domains: DNS injection from specific IP ranges (known GFW injection IPs include 8.7.198.45, 37.186.58.14, 243.185.187.39, and approximately eight others documented by the academic literature), plus TCP RST injection at the TLS handshake stage for domains that use HTTPS. GFW RST injection fires on ClientHello SNI inspection and arrives at probes in 8–12 ms — within the sub-15 ms injection threshold but distinguishable from TSPU's sub-3 ms timing by the additional routing hops from probe to the injection point. TTL analysis of the injected RSTs, which arrive with TTL values consistent with a device 3–5 hops from the probe, places the injection hardware at backbone exchange points rather than ISP-level devices.
NetClean / ISP-level transparent proxies (Turkey)
Turkish court-ordered blocking does not use a centralized DPI system in the same architectural sense as TSPU or GFW. Instead, court orders are distributed to ISPs through the Information Technologies Authority (BTK), and each ISP implements the block independently — some via DNS NXDOMAIN, others via HTTP transparent proxy, and some via TLS SNI filtering. Voidly's block page fingerprint library contains 47 distinct Turkish block page variants, but a notable subset of ISPs serving entirely different geographic regions return bit-for-bit identical block pages, suggesting that the BTK delivers a standardized block page template along with the court order rather than allowing ISPs to design their own.
The following Rust struct captures the fields Voidly uses to represent a DPI vendor signature, along with the classification function that scores a measurement against known signatures:
/// A known DPI vendor or filtering system signature.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DpiSignature {
/// Human-readable vendor or system name (e.g. "TSPU", "GFW", "ARRS")
pub vendor_name: &'static str,
/// RST injection arrives faster than this threshold (ms) from ClientHello sent.
/// None means timing is not a reliable discriminator for this vendor.
pub rtt_threshold_ms: Option<u32>,
/// Expected TTL range of the injected RST at the probe (hop-count signature).
/// (min_ttl, max_ttl) as observed at the probe after routing.
pub rst_source_ttl_range: Option<(u8, u8)>,
/// Known injection IP addresses for DNS false-answer injection.
pub expected_injection_ips: &'static [&'static str],
/// SHA-256 prefix (first 8 bytes) of known block page HTML bodies.
/// Multiple variants stored; a match on any qualifies.
pub block_page_hash_prefix: &'static [[u8; 8]],
}
pub const KNOWN_DPI_SIGNATURES: &[DpiSignature] = &[
DpiSignature {
vendor_name: "TSPU",
rtt_threshold_ms: Some(3),
rst_source_ttl_range: Some((58, 63)), // ~1–4 hops from backbone IXP
expected_injection_ips: &[], // RST injection, not DNS
block_page_hash_prefix: &[], // TSPU does not serve block pages; drops/RSTs
},
DpiSignature {
vendor_name: "GFW",
rtt_threshold_ms: Some(15),
rst_source_ttl_range: Some((54, 62)), // 3–5 hops from backbone exchange
expected_injection_ips: &[
"8.7.198.45",
"37.186.58.14",
"243.185.187.39",
"93.46.8.89",
"59.24.3.174",
"1.1.1.3", // GFW-hijacked, not Cloudflare
],
block_page_hash_prefix: &[], // GFW resets rather than serving block pages
},
DpiSignature {
vendor_name: "ARRS",
rtt_threshold_ms: None,
rst_source_ttl_range: None,
expected_injection_ips: &[
"10.10.34.35", // Internal TIC test resolver — appears in NXDOMAIN responses
],
block_page_hash_prefix: &[
[0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04], // variant 1 (filtered.ir)
[0x7c, 0xf9, 0x1a, 0x3e, 0xb0, 0x22, 0xd1, 0x55], // variant 2 (Farsi judicial)
],
},
];
/// Score a measurement against a DPI signature. Returns a float in [0.0, 1.0].
/// Signals that fire contribute to the score; the maximum is 1.0 (all signals match).
pub fn classify_dpi_vendor(
rst_rtt_ms: Option<u32>,
rst_ttl: Option<u8>,
dns_answer_ips: &[&str],
block_page_hash_prefix: Option<[u8; 8]>,
sig: &DpiSignature,
) -> f32 {
let mut score: f32 = 0.0;
let mut possible: f32 = 0.0;
// RST timing threshold
if let Some(threshold) = sig.rtt_threshold_ms {
possible += 0.35;
if let Some(rtt) = rst_rtt_ms {
if rtt <= threshold {
score += 0.35;
}
}
}
// RST source TTL range
if let Some((min_ttl, max_ttl)) = sig.rst_source_ttl_range {
possible += 0.25;
if let Some(ttl) = rst_ttl {
if ttl >= min_ttl && ttl <= max_ttl {
score += 0.25;
}
}
}
// DNS injection IP match
if !sig.expected_injection_ips.is_empty() {
possible += 0.25;
let matched = dns_answer_ips
.iter()
.any(|ip| sig.expected_injection_ips.contains(ip));
if matched {
score += 0.25;
}
}
// Block page hash prefix match
if !sig.block_page_hash_prefix.is_empty() {
possible += 0.15;
if let Some(page_hash) = block_page_hash_prefix {
let matched = sig.block_page_hash_prefix.iter().any(|prefix| prefix == &page_hash);
if matched {
score += 0.15;
}
}
}
if possible == 0.0 { 0.0 } else { score / possible }
}ISP-level fingerprinting
Within a country, different ISPs often implement the same court order or blocking directive differently, revealing the equipment they have deployed. This is particularly visible in Russia and Turkey, where multiple national operators receive the same block list but implement it through different technical mechanisms. The interference-type distribution per ASN is itself a fingerprint.
Rostelecom (Russia, AS12389): Primarily TLS SNI blocking via TSPU middleboxes deployed at backbone IXPs. Interference-type distribution for TSPU-enforced domains: approximately 60% tls_interference (SNI-triggered RST), 25% throttling (rate-limited flows at precisely configured values), 15% http_blocking (residual HTTP-layer blocks for domains where TSPU enforcement is not yet configured). Rostelecom's TSPU is the reference implementation — it shows the most consistent and lowest-latency RST injection timing in the Russian ASN population.
MTS (Russia, AS8359): DNS injection dominant. MTS's resolver returns injected NXDOMAIN or bogon IPs, and the injected DNS responses always carry a TTL of exactly 60 seconds regardless of what the domain's real TTL would be. This uniform TTL is a hardcoded value in the injection software and is diagnostic of MTS's filtering implementation — no legitimate resolver returns a 60-second TTL for every domain it resolves.
Turkcell (Turkey, AS9121 sub-allocation): HTTP redirect to block page via transparent proxy on port 80. When a probe makes an HTTP request to a blocked domain, Turkcell's proxy intercepts it and returns a redirect to the BTK block page. HTTPS traffic passes through the transparent proxy unmodified — Turkcell does not perform TLS interception — but CDN-hosted HTTPS content may encounter GeoIP-based blocking from the CDN rather than from Turkcell's equipment.
TTNet (Turkey, also under AS9121 with a sub-allocation separate from Turkcell): DNS NXDOMAIN. Despite sharing the parent AS with Turkcell, TTNet's residential and business subscribers see DNS-level blocking rather than HTTP-level blocking, because TTNet operates its own recursive resolvers that are programmed to return NXDOMAIN for BTK-listed domains.
The following Python dataclass represents an ISP blocking fingerprint in the Voidly infrastructure classification layer:
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class IspBlockingFingerprint:
"""
Fingerprint for a specific ISP's blocking implementation.
Populated from historical measurement data per ASN.
"""
asn: int
isp_name: str
country_code: str
# Observed distribution of interference types (fractions summing to ~1.0)
# e.g. {'tls_interference': 0.60, 'throttling': 0.25, 'http_blocking': 0.15}
interference_type_distribution: dict[str, float] = field(default_factory=dict)
# If this ISP injects DNS responses: what TTL do the injected responses carry?
# None if DNS injection is not observed for this ISP.
dns_response_ttl_if_injected: Optional[int] = None
# SHA-256 (hex) of the most common block page body returned by this ISP.
# None if the ISP does not serve an HTTP block page.
typical_block_page_hash: Optional[str] = None
# Known injection IP addresses used by this ISP in DNS responses.
dns_injection_ips: list[str] = field(default_factory=list)
def match_score(
self,
observed_interference_types: dict[str, float],
observed_dns_ttl: Optional[int] = None,
observed_block_page_hash: Optional[str] = None,
observed_dns_ips: Optional[list[str]] = None,
) -> float:
"""
Score how well an observed measurement matches this ISP fingerprint.
Returns a value in [0.0, 1.0].
"""
score = 0.0
weight_total = 0.0
# Interference type distribution match (cosine similarity)
if self.interference_type_distribution and observed_interference_types:
keys = set(self.interference_type_distribution) | set(observed_interference_types)
dot = sum(
self.interference_type_distribution.get(k, 0.0)
* observed_interference_types.get(k, 0.0)
for k in keys
)
mag_a = sum(v ** 2 for v in self.interference_type_distribution.values()) ** 0.5
mag_b = sum(v ** 2 for v in observed_interference_types.values()) ** 0.5
if mag_a > 0 and mag_b > 0:
score += 0.5 * (dot / (mag_a * mag_b))
weight_total += 0.5
# DNS injection TTL match
if self.dns_response_ttl_if_injected is not None:
weight_total += 0.2
if observed_dns_ttl == self.dns_response_ttl_if_injected:
score += 0.2
# Block page hash match
if self.typical_block_page_hash is not None:
weight_total += 0.2
if observed_block_page_hash == self.typical_block_page_hash:
score += 0.2
# DNS injection IP match
if self.dns_injection_ips and observed_dns_ips:
weight_total += 0.1
if any(ip in self.dns_injection_ips for ip in observed_dns_ips):
score += 0.1
return score / weight_total if weight_total > 0 else 0.0TTL analysis for middlebox detection
IP packets carry a Time-To-Live (TTL) field that is decremented by one at each router hop. When a packet leaves its origin, it starts at a standard initial TTL — typically 64 for Linux systems, 128 for Windows, or 255 for some network equipment. By observing the TTL at which an injected RST or ICMP message arrives at the probe, and knowing the standard initial TTL values, Voidly can estimate how many hops away the injecting device sits from the probe.
A legitimate RST from a remote server (say, a Google server in Europe reached by a European probe) would arrive with a TTL consistent with 5–10 hops of routing. An injected RST from a backbone middlebox in the same country as the probe might arrive with TTL 60, suggesting the device is 4 hops away from the probe (initial TTL 64, minus 4 hops). This hop count difference distinguishes backbone-level filtering equipment from ISP-level filtering equipment:
def infer_middlebox_distance(
observed_ttl: int,
expected_initial_ttl: int = 64,
) -> int:
"""
Estimate the number of hops between the probe and the device that injected
an RST or ICMP packet, based on the TTL observed at the probe.
observed_ttl: the TTL value in the injected packet as received by the probe
expected_initial_ttl: the TTL the injecting device likely started with.
Standard values: 64 (Linux/FreeBSD/macOS), 128 (Windows), 255 (Cisco IOS).
Defaults to 64 (most common for Linux-based filtering appliances).
Returns an estimated hop count from the middlebox to the probe.
"""
return expected_initial_ttl - observed_ttl
# Interpretation guide:
# hop_count == 0 → injected by a device on the same link (rare, ISP edge)
# hop_count in [1, 4] → local backbone; filtering at backbone IXP or transit provider
# hop_count in [5, 15] → distant backbone or upstream transit — regional filtering node
# hop_count > 15 → TTL consistent with a real remote server (not a middlebox)
# — RST may be legitimate or the TTL assumption is wrong
BACKBONE_MAX_HOPS = 4 # TTL-derived hop counts <= this suggest backbone placement
ISP_EDGE_MAX_HOPS = 8 # TTL-derived hop counts <= this suggest ISP-edge placement
def classify_middlebox_placement(observed_ttl: int, expected_initial_ttl: int = 64) -> str:
hops = infer_middlebox_distance(observed_ttl, expected_initial_ttl)
if hops <= BACKBONE_MAX_HOPS:
return "backbone_isp"
if hops <= ISP_EDGE_MAX_HOPS:
return "isp_edge"
return "remote_or_unknown"Applied to the Russian TSPU dataset, TTL analysis places TSPU injection devices at 1–4 hops from probes across all measured ISPs, consistent with deployment at national backbone IXPs (MIXA, MSK-IX, and similar exchange points) rather than at individual ISP-level routers. GFW RST injection shows a wider TTL spread — 3–8 hops — reflecting the GFW's distributed deployment across multiple provincial backbone nodes rather than a single central chokepoint.
Infrastructure mapping via OSINT cross-referencing
Technical fingerprinting from network signals provides one evidence stream. The second stream is open-source intelligence: government procurement records, technical standards documents, regulatory filings, and academic literature that independently document which equipment is deployed where. When these two streams converge, the confidence in an infrastructure identification increases substantially.
Government procurement records: Russia's TSPU contracts are published in part through zakupki.gov.ru, Russia's federal procurement portal. Tenders for “TSPU” equipment from Rostelecom and other backbone operators name the technical specifications required under the Sovereign Internet Law and, in some cases, the equipment vendors responding to the tender. Turkey's Information Technologies Authority (BTK) publishes similar procurement notices for filtering infrastructure through the Turkish public procurement system, and civil society organizations have cross-referenced those records with Voidly's ISP-level fingerprints.
Technical standards documents: Russia's SORM-3 framework (the third generation of the System of Operative Investigative Measures) specifies interface requirements for TSPU-compatible equipment in technical regulatory documents published by the Federal Security Service (FSB). These specifications describe the packet processing pipeline and timing requirements that explain the sub-3 ms RST injection timing seen in Voidly data: the TSPU interface spec requires response latency below 5 ms to avoid degrading user experience on non-blocked traffic.
Academic papers on GFW infrastructure: Researchers at CAIDA, Princeton, and several Chinese universities (working on public academic papers before institutional constraints tightened) have published detailed analyses of GFW architecture. The known GFW DNS injection IP list in Voidly's DpiSignature struct was originally compiled from this academic literature and has been extended through Voidly's own measurement of DNS injection patterns.
BGP topology from RIPE NCC and RouteViews: RIPE NCC WHOIS data and BGP topology maps show the transit relationships between ASNs — which ASNs are customer networks versus transit providers, and where the backbone IXPs sit in the topology. This topology data lets Voidly place a measured middlebox hop count in the context of the actual routing path, confirming whether a 4-hop injection device is in a position topologically consistent with a backbone IXP.
The triangulation between technical fingerprints and OSINT records is methodologically important. If a procurement record documents a purchase of Ericsson DPI equipment and Voidly's timing signatures are consistent with Ericsson's documented traffic shaping approach (available in public technical documentation), that convergence strengthens the infrastructure identification beyond what either source alone would support.
The censorship_infrastructure field in the dataset
Voidly exposes infrastructure identification through the censorship_infrastructurefield in the measurement dataset. The field is typed Optional[str] and takes values from a controlled vocabulary:
# Known values for the censorship_infrastructure field.
# These correspond to identified DPI systems or infrastructure categories.
CENSORSHIP_INFRASTRUCTURE_VALUES = {
"tspu_rst": "Russia TSPU RST injection at backbone level",
"tspu_throttle": "Russia TSPU rate-limiting / throttling mode",
"gfw_dns_injection": "China GFW DNS injection (false answer from known GFW IPs)",
"gfw_rst": "China GFW TCP RST injection at TLS handshake",
"arrs_dns": "Iran ARRS DNS NXDOMAIN injection",
"arrs_block_page": "Iran ARRS HTTP transparent proxy block page",
"netsweeper_http": "NetSweeper HTTP transparent proxy (documented block page variant)",
"sandvine_rst": "Sandvine PacketLogic RST injection (documented signature)",
"unknown_transparent_proxy": "HTTP transparent proxy — vendor not identified",
"btk_dns_nxdomain": "Turkey BTK-ordered DNS NXDOMAIN (ISP-level resolver)",
"btk_http_redirect": "Turkey BTK-ordered HTTP redirect to block page",
None: "Infrastructure not identified or confidence below threshold",
}Population rules: the censorship_infrastructure field is populated only when confidence_tier == VERIFIED_INCIDENT and the DPI classification score returned by classify_dpi_vendor() exceeds 0.80. Below that threshold, the field is left null rather than surfacing a low-confidence guess as authoritative data. Coverage in the current dataset: 67% of verified incidents have a non-null censorship_infrastructure value. The remaining 33% either have signatures that do not match known vendor patterns at the required confidence level, or are from countries where Voidly's OSINT cross-referencing has not yet established ground truth for the infrastructure in use.
The field is CC BY 4.0 like the rest of the dataset, and Voidly's methodology documentation explicitly frames it as technical inference from network signals rather than legal attribution. Citing this field as definitive proof of government equipment use in a legal proceeding would require additional evidence beyond what passive network measurement can establish.
Country case study: Russia's TSPU rollout trajectory
The TSPU deployment is the clearest documented case in the Voidly dataset of a nation-state censorship infrastructure rollout that is visible as a time-series transition in measurement data.
2019: Russia's Sovereign Internet Law (Federal Law 90-FZ) is signed, mandating that backbone ISPs install TSPU equipment supplied or approved by the federal telecommunications regulator Roskomnadzor. ISPs are required to accept centralized routing instructions via a technical interface at the TSPU device level.
2021: TSPU equipment comes online at five major backbone operators — Rostelecom (AS12389), MTS (AS8359), VimpelCom (AS3216), MegaFon (AS31133), and ER-Telecom (AS41668). Voidly's measurement data from this period shows the initial TSPU activation as a sudden increase in tspu_rst classifications for previously DNS-only blocked domains on Rostelecom, with the pattern propagating to the other four operators over subsequent months.
2022 (post-Ukraine invasion, February onward): A sharp surge in TLS interference measurements across all five TSPU-equipped ISPs, beginning within 48 hours of the invasion. Voidly detects the switch-on of active TSPU enforcement via a coordinated increase in tspu_rst classifications across multiple ASNs simultaneously — the kind of synchronized change that is not consistent with independent ISP decisions and is consistent with centralized activation through the Roskomnadzor-controlled TSPU management interface. Facebook, Instagram, and Twitter are blocked in this wave.
2023: TSPU throttling mode begins targeting YouTube and Twitter/X. Voidly's throttling measurements for YouTube URLs served from Google's Russian CDN nodes show the flat-rate transfer profile characteristic of TSPU token-bucket enforcement: body download rate capped at exactly 128 KB/s with no burst, for probes at Rostelecom and MegaFon. After significant public backlash, Roskomnadzor partially reverses the YouTube throttle in late 2023 for a period before reinstating it at reduced intensity.
The TSPU rollout is visible in the dataset as a structural shift in the interference_type distribution for Russian measurements:
| Period | Dominant interference_type (Russia, all ASNs) | TSPU-attributed share |
|---|---|---|
| Pre-2021 | dns_tampering (~70%) | < 5% (TSPU not yet active) |
| 2021 activation | tls_interference overtakes dns_tampering | ~40% and rising |
| Post-Feb 2022 | tls_interference dominant (~60%) | ~65% of all Russian TLS interference |
| 2023–present | Split: tls_interference + throttling | ~70% including throttling mode |
This case study illustrates the value of longitudinal infrastructure tracking: the activation of TSPU enforcement is not just a political event documented in news reporting, but a measurable technical transition in the dataset with a specific onset date, propagation timeline across ASNs, and quantifiable change in interference-type distribution. That granularity is what makes the censorship_infrastructurefield useful for research rather than decorative.
Related technical articles:
For the TLS interference measurement methodology that provides the RST timing data used for DPI fingerprinting: How Voidly measures TLS censorship: certificate forgery, SNI blocking, and handshake interference →
For the block page fingerprint library that backs the HTTP-layer infrastructure identification: Voidly's block page fingerprint library: detecting censorship signatures across 2,300+ known pages →
For the cross-source verification that confirms infrastructure-level events from the OONI, CensoredPlanet, and IODA signals: Cross-source censorship verification: reconciling OONI, CensoredPlanet, and IODA →
For building the entity-level OSINT profiles that cross-reference procurement records and technical standards: Building a digital-footprint reconnaissance pipeline for OSINT investigations →
For the censorship-resistant VPN infrastructure that uses this infrastructure mapping to route around known filtering equipment: Building a distributed VPN with intelligent routing →