Skip to content

Bracket IPv6 addresses in more cases#2363

Open
fatelei wants to merge 2 commits intosquid-cache:masterfrom
fatelei:fix_ipv6
Open

Bracket IPv6 addresses in more cases#2363
fatelei wants to merge 2 commits intosquid-cache:masterfrom
fatelei:fix_ipv6

Conversation

@fatelei
Copy link

@fatelei fatelei commented Jan 30, 2026

IPv6 addresses in request target and Host header value should be
bracketed. Ip::Address::toStr() calls do not bracket. The exact
effects of this fix are not known because this improvement was triggered
as a bug fix for Squid v6, and that particular bug does not affect Squid
v7+. buildFakeRequest() code analysis suggests that Squid v7+ was
creating fake CONNECT requests with an unbracketed IPv6 Host header
value (but that header may be effectively unused and that request
target was bracketed correctly).

@squid-anubis squid-anubis added the M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels label Jan 30, 2026
@squid-anubis
Copy link
Collaborator

Cannot create a git commit message from PR title and description.

Error while parsing PR description body: the line is too long 104>72

Problematic parser input:

2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(35) front: Pipeline 0x55db99641660 front 0x55db99642e802

Please see PR title and description formatting requirements for more details.

This message was added by Anubis bot. Anubis will add a new message if the error text changes. Anubis will remove M-failed-description label when there are no corresponding failures to report.

@fatelei fatelei changed the title fix: fix ipv6 address malformed destination 0.0.10.40:3 fix: fix ipv6 address malformed Jan 30, 2026
@squid-anubis squid-anubis added M-failed-other https://github.com/measurement-factory/anubis#pull-request-labels M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels and removed M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels M-failed-other https://github.com/measurement-factory/anubis#pull-request-labels labels Jan 30, 2026
Copy link
Contributor

@rousskov rousskov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that Squid code should be modified. Please do not interpret my review as implying that there are no relevant Squid bugs here! Once my specific change request is addressed, if there are no new surprises, I plan to fix this PR title/description and approve this PR.


In my tests, the second presented python script produces an invalid CONNECT request:

2026/01/30 09:43:44.356| 11,2| client_side.cc(1237) parseHttpRequest: HTTP Client REQUEST:
---------
CONNECT 2600:3c03::f03c:94ff:fef6:a3ae:443 HTTP/1.1
Host: 2600:3c03::f03c:94ff:fef6:a3ae:443
Accept: */*

The above request has invalid target (missing brackets). That is, IMHO, an httpx bug. The Host header is similarly malformed. There is no need to discuss that httpx bug in this pull request -- we should be focusing on Squid bugs here.

Also note that its malformed IP-based Host header does not match the test-ipv6.com Host header in the Python script, but that mismatch is not necessarily an httpx bug -- headers parameter in client.get() call could refer to GET headers rather than CONNECT headers. I am only noting this here because it may help interpret the test correctly. There is no need to discuss this aspect in this pull request.

In my tests, Squid v7+ correctly rejects that malformed CONNECT:

2026/01/30 09:43:44.357| 23,2| Uri.cc(550) parse: error: garbage after host:port in CONNECT target
    exception location: Uri.cc(341) parse  rawUrl[34]=2600:3c03::f03c:94ff:fef6:a3ae:443
err=ERR_INVALID_URL/- ... 1769784224.000370     12 127.0.0.1:37452 NONE_NONE/400 3629 - 2600:3c03::f03c:94ff:fef6:a3ae:443 - HIER_NONE/- text/html

I can reproduce the 0.0.10.40:3 problem with Squid v6, which is no longer supported by the Squid Project.

@rousskov rousskov added the S-waiting-for-author author action is expected (and usually required) label Jan 30, 2026
@yadij yadij changed the title fix: fix ipv6 address malformed Fix ipv6 address malformed Jan 31, 2026
@rousskov rousskov self-requested a review February 1, 2026 03:57
@rousskov rousskov added S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box and removed S-waiting-for-author author action is expected (and usually required) labels Feb 1, 2026
@rousskov rousskov changed the title Fix ipv6 address malformed Bracket IPv6 addresses in more cases Feb 2, 2026
@squid-anubis squid-anubis removed the M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels label Feb 2, 2026
Copy link
Contributor

@rousskov rousskov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have adjusted PR title/description. If you can detail what specific use cases this PR fixes (from Squid master/v8 point of view!), please adjust PR description further to describe those use cases.

if (pinning.serverConnection != nullptr) {
static char ip[MAX_IPSTRLEN];
connectHost = pinning.serverConnection->remote.toStr(ip, sizeof(ip));
connectHost = pinning.serverConnection->remote.toHostStr(ip, sizeof(ip));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/client_side.cc:3097:65: error: invalid conversion from ‘unsigned int’ to ‘const char*’

This change (and a similar change further below) does not compile because toHostStr() does not return an SBuf while connectHost is an SBuf. For a solution example, see AnyP::Uri::hostOrIp() that implements a similar to-SBuf conversion of a toHostStr() result.

And please test PR code.

static char ip[MAX_IPSTRLEN];
assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION));
request->url.host(clientConnection->local.toStr(ip, sizeof(ip)));
request->url.host(clientConnection->local.toHostStr(ip, sizeof(ip)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change does not compile. Please see the other change request for more related details, but the solution here is going to be a bit different. Most likely, you would be able to call host(ip) after filling ip using toHostStr().

@rousskov
Copy link
Contributor

rousskov commented Feb 2, 2026

Here is a copy of the original (v6-based?) PR description by @fatelei, detailing the problem and the tests:


my squid config

acl test_ipv6_host dst 2600:3c03::f03c:94ff:fef6:a3ae/128

acl test_ipv6_domain dstdomain .test-ipv6.com

http_access allow test_ipv6_host
http_access allow test_ipv6_domain

test script in python

import httpx

transport = httpx.HTTPTransport(proxy="http://127.0.0.1:3128")

with httpx.Client(transport=transport, timeout=30.0) as client:
    response = client.get(
        "http://[2600:3c03::f03c:94ff:fef6:a3ae]/",
        headers={"Host": "test-ipv6.com"}
    )
    print(response.status_code)

it work in http, but in https it fail

import httpx

transport = httpx.HTTPTransport(proxy="http://127.0.0.1:3128")

with httpx.Client(transport=transport, timeout=30.0) as client:
    response = client.get(
        "https://[2600:3c03::f03c:94ff:fef6:a3ae]/",
        headers={"Host": "test-ipv6.com"}
    )
    print(response.status_code)

there is relate log

2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(35) front: Pipeline 0x55db99641660 front 0x55db99642e802
2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(35) front: Pipeline 0x55db99641660 front 0x55db99642e803
2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(35) front: Pipeline 0x55db99641660 front 0x55db99642e803
2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(35) front: Pipeline 0x55db99641660 front 0x55db99642e802
2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(57) popMe: Pipeline 0x55db99641660 drop 0x55db99642e80*3
2026/01/30 06:37:27.331 kid1| 33,3| Pipeline.cc(31) front: Pipeline 0x55db99641660 empty
2026/01/30 06:37:27.331 kid1| 33,3| client_side.cc(990) kick: conn11 local=127.0.0.1:3128 remote=127.0.0.1:34438 FD 14 flags=1: calling readNextRequest()
2026/01/30 06:37:27.331 kid1| 33,3| client_side_request.cc(237) ~ClientHttpRequest: httpRequestFree: 0.0.10.40:3

==> /var/log/squid/access.log <==
127.0.0.1 - - [30/Jan/2026:06:37:27 +0000] "CONNECT 0.0.10.40:3 HTTP/1.1" 403 3353 TCP_DENIED:HIER_NONE 0 "-" "-" - text/html

==> /var/log/squid/cache.log <==
2026/01/30 06:37:27.332 kid1| 33,2| Server.cc(193) doClientRead: conn11 local=127.0.0.1:3128 remote=127.0.0.1:34438 FD 14 flags=1: got flag -1; (104) Connection reset by peer
2026/01/30 06:37:27.332 kid1| 33,3| client_side.cc(4005) terminateAll: 0/1 after ERR_CLIENT_GONE/errno=104
2026/01/30 06:37:27.332 kid1| 33,2| client_side.cc(617) swanSong: conn11 local=127.0.0.1:3128 remote=127.0.0.1:34438 flags=1
2026/01/30 06:37:27.332 kid1| 33,3| client_side.cc(4005) terminateAll: 0/1 after ERR_NONE/WITH_CLIENT
2026/01/30 06:37:27.332 kid1| 33,3| client_side.cc(3966) unpinConnection:
2026/01/30 06:37:27.332 kid1| 33,3| client_side.cc(673) ~ConnStateData: conn11 local=127.0.0.1:3128 remote=127.0.0.1:34438 flags=1

here it connect 0.0.10.40:3, this is not right relate issue: langgenius/dify#31637

@rousskov rousskov added S-waiting-for-author author action is expected (and usually required) and removed S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box labels Feb 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-for-author author action is expected (and usually required)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants