A forward proxy acts on behalf of the client to access the target. The client first decides whether to delegate a specific connection or request to the proxy, which then forwards it to the target according to the target and policy. Configuring a proxy address does not mean that all programs, DNS, UDP, or system traffic automatically pass through it.
When understanding the proxy path, you must simultaneously track three questions: who selects the proxy, who resolves the target domain name, and whether each segment is encrypted. Looking only at the final target IP or a browser "proxy connected" prompt cannot answer these questions.
Scenario
What the client sends to the proxy
Proxy's main task
Standard HTTP proxy request
HTTP request with absolute-form target
Parse HTTP and forward
HTTP CONNECT
Host and port
Establish byte tunnel
SOCKS5 CONNECT
Binary target address and port
Establish TCP relay
SOCKS5 UDP ASSOCIATE
Control association, followed by UDP encapsulation
Relay UDP based on datagram target
PAC
Execute selection rules locally
Select DIRECT or proxy candidate; does not carry traffic
HTTP Request Proxy and CONNECT
When requesting a plaintext site via a standard HTTP proxy, the request target usually looks like GET http://example.com/index.html HTTP/1.1; the proxy can read and process HTTP. When accessing an HTTPS target, the client often first sends CONNECT example.com:443 HTTP/1.1 along with the corresponding Host, and after receiving a successful 2xx response, performs a TLS handshake with the target within the tunnel.
Bytes after a successful CONNECT are no longer parsed as the body of a standard HTTP message for that request. Typically, client-to-proxy and proxy-to-target are two independent TCP connections; the proxy concatenates byte transmission capabilities, rather than extending a single TCP connection intact to the server.
CONNECT itself does not provide encryption, nor is it limited to HTTPS. The proxy can restrict target ports and destinations; the client cannot equate a successful proxy connection with permission to access any address. Proxy authentication failure usually corresponds to 407 and Proxy-Authenticate, while the target service's 401 is a separate layer. RFC 9110: CONNECT
HTTPS Proxy and HTTPS Target are Two Different Things
http://proxy.example:8080 and https://proxy.example:8443 describe the transport method from client to proxy; the https:// in the target URL describes the target service using TLS. CONNECTing to an HTTPS target on an HTTPS proxy can form an outer proxy TLS and an inner target TLS, with different authentication objects.
A proxy that does not terminate the inner TLS cannot see the target HTTP content, but still knows the explicit CONNECT target, time, and traffic volume. ECH can change the visible content of the inner ClientHello, but it does not erase the CONNECT target already sent to that proxy. If the client trusts the alternative certificate issued by the proxy and allows TLS inspection, the actual identity and confidentiality boundaries have already changed.
HTTP/2 and HTTP/3 can also carry their respective CONNECT mechanisms; do not assume all proxy connections are a single HTTP/1.1 connection building only one tunnel. The standard CONNECT TCP byte tunnel and CONNECT-UDP are different capabilities; the latter has specific UDP proxy protocol conventions. RFC 9298
SOCKS5: Method Selection, Authentication, and Commands Cannot Be Confused with TCP Handshake
First, establish a TCP connection to the proxy, then negotiate available authentication methods; when selecting methods like username/password, there is a sub-negotiation, followed by sending CONNECT, BIND, or UDP ASSOCIATE commands. These stages cannot be collectively referred to as a fixed "three-way handshake."
Domain name addresses contain 1 B length and name bytes, with no trailing NUL; port uses 2 B network byte order. The BND.ADDR/PORT in the CONNECT reply is the binding endpoint the proxy uses for the target connection, not echoing the DST as is. RFC 1928
The username/password sub-negotiation has its own version field as 1, and cannot be written as SOCKS main protocol version 5. This method transmits credential bytes directly and does not automatically provide encryption; security depends on the outer transport and deployment boundaries. RFC 1929
Complete Address Example: Domain Name CONNECT and IPv4 Header
importipaddressname=b'example.com'request=bytes([5,1,0,3,len(name)])+name+(443).to_bytes(2,'big')assertrequest.hex()=='050100030b6578616d706c652e636f6d01bb'assertlen(request)==18n=request[4]assertrequest[5:5+n].decode('ascii')=='example.com'assertint.from_bytes(request[5+n:7+n],'big')==443# No SOCKS fragmentation, IPv4 target. Here DATA is just teaching bytes, not actual DNS packets.
udp_head=bytes([0,0,0,1])+ipaddress.ip_address('192.0.2.53').packed+(53).to_bytes(2,'big')packet=udp_head+b'DATA'assertlen(udp_head)==10andlen(packet)==14assertudp_head.hex()=='00000001c00002350035'assertint.from_bytes(packet[8:10],'big')==53print('CONNECT request / UDP encapsulation header:',len(request),len(udp_head))
This example only checks encoding, not implementing proxy connection, authentication, or relay. SOCKS5 does not provide general IP-layer forwarding; for example, ICMP is not sent as TCP content directly through CONNECT.
UDP ASSOCIATE: Control Connection is Not UDP-over-TCP
The client establishes the association via TCP command; the address and port in the command describe the client UDP endpoint expected to be used, which can be filled with zeros if unknown. The proxy replies with an available relay endpoint; the client then sends each UDP datagram with a SOCKS header to the relay, specifying the actual target in the header; do not treat the zero address in the association request as the final destination for each datagram.
Returned data is also sent by the relay with a SOCKS header to the client, used to identify the remote source. The association terminates when the TCP control connection closes; UDP may still be lost or reordered, and the TCP control channel does not retransmit for it. FRAG=0 means unfragmented; SOCKS layer fragmentation support is optional, and implementations that do not support it discard packets with non-zero FRAG; this is also different from IP fragmentation.
The SOCKS UDP header for IPv4 targets is 10 B, for IPv6 targets is 22 B, and for domain name targets is 7 + name byte count, plus outer UDP/IP overhead. A TCP proxy being reachable does not prove UDP relay is reachable, and client applications may not implement UDP ASSOCIATE at all.
Where is DNS: Address Type and Client Implementation Jointly Determine
When the client resolves locally first and sends an IP, the proxy cannot revoke the local DNS query that has already occurred. When sending ATYP=Domain name, it is handed to the proxy side to resolve or route according to its own policy; this does not mean the proxy must use a specific public DNS.
curl distinguishes between local resolution for socks5:// and proxy-side resolution for socks5h://. The following is for manual observation only when a corresponding local proxy is available; execution will initiate real target requests:
--connect-timeout is also not the total timeout for the entire download. Proxy host discovery itself, application pre-resolution, DoH, and other processes not using this proxy still need to be checked separately; you cannot assert that the entire system has no local DNS traffic based solely on one successful curl. curl proxy options
Changing the domain name to an IP changes more than just packet length
Both paths can ultimately access the same target, but the evidence received by the proxy is different: the IP path has no original domain name, while the domain name path has length bytes and the name itself. This demonstrates the responsibility boundary of a command, and does not declare that all system DNS passes through the proxy based on this.
Preparing the visual
Changing the domain name to an IP changes more than just packet length
ATYP determines whether the request carries a name or an address. DNS queries already made locally do not disappear just because they later enter an encrypted tunnel.
{"id":"socks-address-and-dns","title":"Changing the domain name to an IP changes more than just packet length","summary":"ATYP determines whether the request carries a name or an address. DNS queries already made locally do not disappear just because they later enter an encrypted tunnel.","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"presets\" role=\"group\" data-i18n-label=\"mode\"><button data-mode=\"local\" data-i18n=\"local\"></button><button data-mode=\"remote\" data-i18n=\"remote\"></button></div><section class=\"panel\"><h3 data-i18n=\"bytes\"></h3><div id=\"bytes\"></div></section><div class=\"metrics\"><div><span data-i18n=\"size\"></span><strong id=\"size\"></strong></div><div><span data-i18n=\"dns\"></span><strong id=\"dns\"></strong></div></div><p id=\"fields\" class=\"message\"></p><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:500;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:500 20px var(--viz-font-ui)}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:var(--viz-font-mono);font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px var(--viz-font-ui);background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n/* Action labels must remain readable across locales and narrow embeds. */\n.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.actions button{overflow-wrap:anywhere;white-space:normal;min-height:58px;padding:8px}\nbutton{overflow-wrap:anywhere}\n@media(min-width:640px){.actions{grid-template-columns:repeat(3,minmax(0,1fr))}}\n\n.metrics span{overflow-wrap:anywhere}\n.panel{border:1px solid var(--rule);border-radius:9px;padding:12px;margin:14px 0;min-width:0}.panel h3{font-size:13px;margin:0 0 10px;color:var(--muted)}.source{font:13px/1.8 var(--viz-font-mono);white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0}.source mark{background:var(--accent-soft);color:var(--ink);border-bottom:2px solid var(--accent)}.source .fault{background:var(--second-soft);border-color:var(--second)}.diagram{display:block;width:100%;height:auto;max-height:320px;margin:14px 0;overflow:visible}.diagram text{fill:var(--ink);font:12px var(--viz-font-ui)}.diagram .edge{stroke:var(--muted);stroke-width:1.5;fill:none}.diagram .edge.on{stroke:var(--accent);stroke-width:3}.diagram .node{fill:var(--surface);stroke:var(--rule);stroke-width:1.5}.diagram .node.on{fill:var(--accent-soft);stroke:var(--accent)}.diagram .node.gold{fill:var(--second-soft);stroke:var(--second)}.log{font:12px/1.8 var(--viz-font-mono);white-space:pre-line;overflow-wrap:anywhere;min-height:7.2em}.table{display:grid;gap:5px;margin:14px 0}.table .tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.table .tr>*{padding:8px 5px;background:var(--surface);border-radius:4px;min-width:0;overflow-wrap:anywhere;font-size:12px}.table .tr .on{background:var(--accent-soft)}.table .tr .gold{background:var(--second-soft)}.choices button{min-height:44px}.metrics strong{min-height:1.6em}.code-line{display:block}.code-line.on{background:var(--accent-soft);border-left:2px solid var(--accent);padding-left:6px}.status-badge{font-size:12px;color:var(--accent)}.tile-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.tile-grid .cell{min-height:40px}.actions button{min-height:48px}.form-field{display:grid;gap:8px;margin:14px 0;font-size:13px}.form-field input{width:100%;font-family:var(--viz-font-ui)}.metrics.three{grid-template-columns:repeat(3,minmax(0,1fr))}.formula{min-height:3.2em}.presets{flex-wrap:wrap}.presets button{flex-basis:25%;min-height:44px}\n\n.budget{display:flex;height:28px;margin:16px 0;background:var(--surface);border-radius:5px;overflow:hidden}.budget i{display:block;background:var(--accent);transition:width .2s}.budget i.gold{background:var(--second)}.intervals{margin:16px 0}.interval{position:relative;height:36px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/36px var(--viz-font-ui);padding-left:7px}.table .tr>*{min-height:4.8em}.formula{white-space:pre-line;min-height:7.2em}.actions:has(>button:only-child){grid-template-columns:1fr}.metrics strong{min-height:3.2em}.rangegrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;margin:14px 0}.rangegrid .cell{min-height:30px;padding:3px 1px;font-size:10px}.message{min-height:7.2em;white-space:pre-line;font:13px/1.8 var(--viz-font-ui);overflow-wrap:anywhere}\n/* Allow CJK hanging punctuation without overflowing a metric's border box. */\n.metrics>div{padding-right:4px}.metrics span{line-break:anywhere}\n\n#bytes{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px}.metrics strong{font-size:17px}","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}let mode='remote';function draw(){const domain=[...new TextEncoder().encode('example.com')],bytes=mode==='remote'?[5,1,0,3,domain.length,...domain,1,187]:[5,1,0,1,192,0,2,10,1,187];cells('bytes',Array.from({length:18},(_,i)=>({text:i<bytes.length?bytes[i].toString(16).padStart(2,'0'):'·',cls:i>=bytes.length?'empty':i===3?'gold':'on'})));set('size',bytes.length);set('dns',t(mode==='local'?'dnsLocal':'dnsRemote'));set('fields','VER=05 CMD=01 RSV=00\\nATYP='+bytes[3]+' PORT=01bb (443)');$('#bytes').dataset.hex=bytes.map(x=>x.toString(16).padStart(2,'0')).join('');pressed(mode);}document.querySelectorAll('[data-mode]').forEach(b=>b.onclick=()=>{mode=b.dataset.mode;draw()});draw();","audio":false,"strings":{"bytes":"CONNECT Bytes","dns":"DNS Responsibility for this Target","dnsLocal":"Local Machine","dnsRemote":"Proxy","heading":"Changing the domain name to an IP changes more than just packet length","intro":"Choose local or proxy resolution to view actual SOCKS5 CONNECT address bytes and resolution responsibility.","local":"Send IP after local resolution","mode":"Resolution Location","remote":"Send domain name for proxy handling","reset":"Reset","scope":"Fixed example.com:443, local resolution teaching value 192.0.2.10; only construct CONNECT command, do not connect to proxy, do not query DNS, do not infer other application traffic.","scopeLabel":"Model Scope and Conventions","size":"Command Length (B)"}}
PAC: Select Route by Target, DIRECT is an Explicit Fallback
PAC's FindProxyForURL returns a proxy candidate string. It is JavaScript in a restricted environment, not a normal script that can arbitrarily access browser page state. Domain name rules are often easier to predict than calling DNS helper functions; isInNet etc. may trigger local resolution, which conflicts exactly with the intent to avoid local resolution.
functionFindProxyForURL(url,host){// Only hand over explicitly controlled internal domain names to direct connection, do not guess server location by country suffix.
host=host.toLowerCase();if(host==='intranet.example'||host.slice(-17)==='.intranet.example'){return'DIRECT';}return'PROXY 127.0.0.1:7890; SOCKS5 127.0.0.1:1080';}
The PAC syntax and helper functions supported by the implementation need to be verified by the client. The example does not have DIRECT at the end, meaning there is no candidate that explicitly allows "proxy failure directly access." If DIRECT is appended, it changes the exit strategy on failure, and cannot be treated as a harmless fixed template.
PAC does not guarantee full re-execution for every request, and you cannot assume HTTPS URLs always contain a path. Taking Chromium as an example, PAC-visible URLs have privacy trimming, proxy selection has caching and failure handling; its SOCKS5 implementation also has its own capability scope. Domain suffix .cn does not prove the target's physical location, and .local involves local name resolution semantics, so it is inappropriate to use it as a rough representative of all intranets. Chromium Proxy Documentation
Locating Failures: Record Evidence by Phase
Phase
Failure Signal
Confirm First
Proxy Selection
Did not pass through expected proxy
Whether the application reads settings, PAC/bypass rules
Connection to Proxy
Timeout, Connection Refused
Address, listening, network, and outer TLS
Proxy Authentication
407, SOCKS method rejected
Method and credential layers
Target Establishment
CONNECT non-2xx, SOCKS REP failure
Proxy policy, target resolution, and egress
Inner TLS
Name or chain failure
Actual target identity and trust material
Business HTTP
401, 403, 5xx
Target service authentication and business processing
UDP Path
TCP successful but UDP no return
Association, relay reachability, encapsulation, and application support
System proxy, environment variables, and application-internal configurations may not override each other; there may also be different authentication and resolution locations in the proxy chain. Separating routes and error phases avoids misjudgments like "all problems change to a different DNS" or "all traffic has been taken over."
Continue Reading
Transparent Proxy and TUN: How to take over traffic when applications have no explicit proxy configuration.