Initial TcpConnectJob implementation. [chromium/src : main]

0 views
Skip to first unread message

mmenke (Gerrit)

unread,
Feb 18, 2026, 12:50:04 PM (3 days ago) Feb 18
to Kenichi Ishibashi, Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org
Attention needed from Kenichi Ishibashi

mmenke added 2 comments

Patchset-level comments
File-level comment, Patchset 4 (Latest):
mmenke . resolved

[bashi] Thoughts? Feel free to take your time. I may send out small CLs on top of this later today/this week, but don't feel like that means there's a rush on this one. I renamed SubJob to Connector, because talking about "jobs" and "sub jobs" was just too confusing, though I may still have slipped up in some places.

The plan is to address the small todos (connect timing, connect attempts, the host resolution callback invocation, etc) in fairly small followups, then do the big ones (second connector), net log (probably not huge, but best done after the second connector is in place), and wiring up to callers (with some integration tests).

File net/socket/tcp_connect_job_connector.cc
Line 195, Patchset 1: if (parent_job_->websocket_endpoint_lock_manager()) {
mmenke . unresolved

Note that this is on top of a CL that I sent to ricea@ that simplifies the WebSocket code needed in this CL. It's possible things will change as that review progresses, but I'll just keep this completely in sync with whatever we do there.

I don't intend to add any unit tests for this call. There are tests at the websocket layer, which pass when the feature is enabled. I may make them run with and without the feature when I actually wire things up, but am not too concerned about this.

Open in Gerrit

Related details

Attention is currently required from:
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
Gerrit-Change-Number: 7589439
Gerrit-PatchSet: 4
Gerrit-Owner: mmenke <mme...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Reviewer: mmenke <mme...@chromium.org>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Comment-Date: Wed, 18 Feb 2026 17:50:00 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Kenichi Ishibashi (Gerrit)

unread,
Feb 19, 2026, 7:05:24 AM (2 days ago) Feb 19
to Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org
Attention needed from Kenichi Ishibashi

Kenichi Ishibashi added 9 comments

Patchset-level comments
File-level comment, Patchset 8 (Latest):
Kenichi Ishibashi . resolved

Sorry I wasn't able to take an actual look. Just leaving minor comments. I'll take a look tomorrow.

File net/socket/tcp_connect_job.h
Line 236, Patchset 8 (Latest): std::unique_ptr<TcpConnectJob::Connector> connector_;
Kenichi Ishibashi . resolved

nit, optional: We can omit `TcpConnectJob::` here.

Line 225, Patchset 8 (Latest): void IfCompletedNotifyDelegate(int result);
Kenichi Ishibashi . unresolved

To me, `NotifyDelegateIfCompleted` is more readable. What do you think?

Line 135, Patchset 8 (Latest): using IPEndPointInfo = base::expected<IPEndPoint, Error>;
Kenichi Ishibashi . unresolved

(Just leaving comments for possible future changes)

When we support HTTPS RR follow-up queries (alias and different target names), each "endpoint" may have different alpns and/or different SvcParams (e.g. ECH config). In the future, we may want to track attempted/attempting endpoint including these information, not just IPEndPoint.

Line 134, Patchset 8 (Latest): // IPEndPoints are provided to child jobs with this API.
Kenichi Ishibashi . unresolved

connector?

Line 81, Patchset 8 (Latest): static constexpr base::TimeDelta kIPv6FallbackTime = base::Milliseconds(300);
Kenichi Ishibashi . unresolved

I guess you intentionally duplicate this and other stuff (e.g. ServiceEndpointOverride) from TransportConnectJob, assuming we will remove TransportConnectJob eventually.

Line 51, Patchset 8 (Latest):// HandleServiceEndpointsUpdated(), and HandleAdvanceWaitingJobs(). Each of
Kenichi Ishibashi . unresolved

Maybe `Connector`? Ditto for other "job"s that refer to `Connector`.

File net/socket/tcp_connect_job_connector.h
Line 39, Patchset 8 (Latest): // Note that there is no start method. Instead, Connectorss are started with a
Kenichi Ishibashi . unresolved

Connectors

Line 39, Patchset 8 (Latest): // Note that there is no start method. Instead, Connectorss are started with a
Kenichi Ishibashi . unresolved

Probably better to put this design choice in the class documentation above?

Also it would be helpful to mention that when the parent job creates an instance of Connector, after we add the second connector in subsequent CLs.

Open in Gerrit

Related details

Attention is currently required from:
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
Gerrit-Change-Number: 7589439
Gerrit-PatchSet: 8
Gerrit-Owner: mmenke <mme...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Reviewer: mmenke <mme...@chromium.org>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Comment-Date: Thu, 19 Feb 2026 12:04:55 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

mmenke (Gerrit)

unread,
Feb 19, 2026, 11:31:00 AM (2 days ago) Feb 19
to Kenichi Ishibashi, Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org
Attention needed from Kenichi Ishibashi

mmenke added 9 comments

Patchset-level comments
Kenichi Ishibashi . resolved

Sorry I wasn't able to take an actual look. Just leaving minor comments. I'll take a look tomorrow.

mmenke

No worries. It's a big CL, and there's no urgency here. Rather get it done well than fast. And just your early comments were really useful - I had thought this was in better shape in terms of comments than it was, so I've spent some time today going over it today, and looking for ways to improve my comments, as well as done some other minor refactors.

mmenke . resolved

Thanks, Kenichi!

File net/socket/tcp_connect_job.h
Line 225, Patchset 8 (Latest): void IfCompletedNotifyDelegate(int result);
Kenichi Ishibashi . resolved

To me, `NotifyDelegateIfCompleted` is more readable. What do you think?

mmenke

"NotifyDelegateIfCompleted " looks too much like "NotifyDelegateOfCompletion" for my tastes. That having been said, there are other options. I've renamed to NotifyDelegateIfDone(). Open to other options.

Line 135, Patchset 8 (Latest): using IPEndPointInfo = base::expected<IPEndPoint, Error>;
Kenichi Ishibashi . unresolved

(Just leaving comments for possible future changes)

When we support HTTPS RR follow-up queries (alias and different target names), each "endpoint" may have different alpns and/or different SvcParams (e.g. ECH config). In the future, we may want to track attempted/attempting endpoint including these information, not just IPEndPoint.

mmenke

I assume we'd still want to connect before crypto ready, so we'd still be passing around raw IPEndpoints, though that does potentially lead to a new weird case: We have connections to non-crypto-ready IPs, but other IPs are crypto ready. What do we do?

It may actually make sense to make a 3rd connection in that case, while keeping old connections around I guess?

Line 134, Patchset 8 (Latest): // IPEndPoints are provided to child jobs with this API.
Kenichi Ishibashi . resolved

connector?

mmenke

Done

Line 81, Patchset 8 (Latest): static constexpr base::TimeDelta kIPv6FallbackTime = base::Milliseconds(300);
Kenichi Ishibashi . unresolved

I guess you intentionally duplicate this and other stuff (e.g. ServiceEndpointOverride) from TransportConnectJob, assuming we will remove TransportConnectJob eventually.

mmenke

TransportConnectJob doesn't have ServiceEndpointOverride - it has EndpointResultOverride, which wraps HostResolverEndpointResult instead of ServiceEndpoint. Using a variant for that didn't seem useful.

But, yea, I duplicated the time stuff because there's not a lot of it, and I imagine us removing the old code. Also, it's entirely possible optimal times would be different for this class than the other one.

Line 51, Patchset 8 (Latest):// HandleServiceEndpointsUpdated(), and HandleAdvanceWaitingJobs(). Each of
Kenichi Ishibashi . resolved

Maybe `Connector`? Ditto for other "job"s that refer to `Connector`.

mmenke

Done. I've audited all "jobs", and replaced all of them with "[Tcp]ConnectJob" or "Connector". Sorry about that, thought I did a better job of getting rid of them yesterday.

File net/socket/tcp_connect_job_connector.h
Line 39, Patchset 8 (Latest): // Note that there is no start method. Instead, Connectorss are started with a
Kenichi Ishibashi . resolved

Connectors

mmenke

Done

Line 39, Patchset 8 (Latest): // Note that there is no start method. Instead, Connectorss are started with a
Kenichi Ishibashi . resolved

Probably better to put this design choice in the class documentation above?

Also it would be helpful to mention that when the parent job creates an instance of Connector, after we add the second connector in subsequent CLs.

mmenke

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
Gerrit-Change-Number: 7589439
Gerrit-PatchSet: 8
Gerrit-Owner: mmenke <mme...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Reviewer: mmenke <mme...@chromium.org>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Comment-Date: Thu, 19 Feb 2026 16:30:54 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

mmenke (Gerrit)

unread,
Feb 19, 2026, 11:37:26 AM (2 days ago) Feb 19
to Kenichi Ishibashi, Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org
Attention needed from Kenichi Ishibashi

mmenke added 1 comment

File net/socket/tcp_connect_job.h
Line 135, Patchset 8 (Latest): using IPEndPointInfo = base::expected<IPEndPoint, Error>;
Kenichi Ishibashi . unresolved

(Just leaving comments for possible future changes)

When we support HTTPS RR follow-up queries (alias and different target names), each "endpoint" may have different alpns and/or different SvcParams (e.g. ECH config). In the future, we may want to track attempted/attempting endpoint including these information, not just IPEndPoint.

mmenke

I assume we'd still want to connect before crypto ready, so we'd still be passing around raw IPEndpoints, though that does potentially lead to a new weird case: We have connections to non-crypto-ready IPs, but other IPs are crypto ready. What do we do?

It may actually make sense to make a 3rd connection in that case, while keeping old connections around I guess?

mmenke

So, right now, what this class needs crypto ready for is to know two things (I think):

1) We know the final value of `svcb_optional_`. This is the part I'm most familiar with, since it's dealt with directly by this ConnectJob, so it's what I've been associating with crypto ready.
2) We know when we have enough information to let the SSL layer connect. This is actually what crypto ready is named after.

If crypto ready information trickles in, when would we know enough to set `svcb_optional_`? I assume it would still have one value for the entire request, but not clear to me if we'd get it early or late. If it's late, we could presumably still complete before we have it, if we know an endpoint is crypto ready (and thus have a SVCB record for it).

Open in Gerrit

Related details

Attention is currently required from:
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
Gerrit-Change-Number: 7589439
Gerrit-PatchSet: 8
Gerrit-Owner: mmenke <mme...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Reviewer: mmenke <mme...@chromium.org>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Comment-Date: Thu, 19 Feb 2026 16:37:21 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: mmenke <mme...@chromium.org>
Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kenichi Ishibashi (Gerrit)

unread,
Feb 20, 2026, 1:39:29 AM (yesterday) Feb 20
to Helmut Januschka, Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org
Attention needed from mmenke

Kenichi Ishibashi voted and added 15 comments

Votes added by Kenichi Ishibashi

Code-Review+1

15 comments

Patchset-level comments
File-level comment, Patchset 17 (Latest):
Kenichi Ishibashi . resolved

Left several comments, but none of them are blocking, so CR+1.

I've checked most tests, but I may miss something. Will try to check them as follow-ups.

Thanks,

File net/socket/tcp_connect_job.h
Line 175, Patchset 17 (Latest): const ServiceEndpoint* FindServiceEndpoint(
Kenichi Ishibashi . unresolved

std::optional<ServiceEndpoint> since we make a copy if we find available one?

Line 135, Patchset 8: using IPEndPointInfo = base::expected<IPEndPoint, Error>;
Kenichi Ishibashi . unresolved

(Just leaving comments for possible future changes)

When we support HTTPS RR follow-up queries (alias and different target names), each "endpoint" may have different alpns and/or different SvcParams (e.g. ECH config). In the future, we may want to track attempted/attempting endpoint including these information, not just IPEndPoint.

mmenke

I assume we'd still want to connect before crypto ready, so we'd still be passing around raw IPEndpoints, though that does potentially lead to a new weird case: We have connections to non-crypto-ready IPs, but other IPs are crypto ready. What do we do?

It may actually make sense to make a 3rd connection in that case, while keeping old connections around I guess?

mmenke

So, right now, what this class needs crypto ready for is to know two things (I think):

1) We know the final value of `svcb_optional_`. This is the part I'm most familiar with, since it's dealt with directly by this ConnectJob, so it's what I've been associating with crypto ready.
2) We know when we have enough information to let the SSL layer connect. This is actually what crypto ready is named after.

If crypto ready information trickles in, when would we know enough to set `svcb_optional_`? I assume it would still have one value for the entire request, but not clear to me if we'd get it early or late. If it's late, we could presumably still complete before we have it, if we know an endpoint is crypto ready (and thus have a SVCB record for it).

Kenichi Ishibashi

To calculate `svcb_optional_` for different endpoints, we probably need to modify the ServiceEndpointRequest API first so that we can distinguish which endpoints are crypto ready and which endpoints are not crypto ready.

I haven't really thought about what kind of interface would be best, maybe something like:
```
class ServiceEndpointRequest {
bool IsEndpointsCryptoReady(const ServiceEndpoint& endpoint) = 0;
};
```

or

```
class ServiceEndpoint {
bool endpoint_crypto_ready = false;
};
```

Not entirely sure about this. Let me loop hel...@januschka.com in since they proposed HTTPS follow-up queries.
https://docs.google.com/document/d/1Xku49GjTNUccpuZtJnImWN90fJgX43d9_rH91vHs7wc/edit?usp=sharing

helmut@: Note that we haven't decided we would like you to work on that. Just sharing information.

Line 81, Patchset 8: static constexpr base::TimeDelta kIPv6FallbackTime = base::Milliseconds(300);
Kenichi Ishibashi . resolved

I guess you intentionally duplicate this and other stuff (e.g. ServiceEndpointOverride) from TransportConnectJob, assuming we will remove TransportConnectJob eventually.

mmenke

TransportConnectJob doesn't have ServiceEndpointOverride - it has EndpointResultOverride, which wraps HostResolverEndpointResult instead of ServiceEndpoint. Using a variant for that didn't seem useful.

But, yea, I duplicated the time stuff because there's not a lot of it, and I imagine us removing the old code. Also, it's entirely possible optimal times would be different for this class than the other one.

Kenichi Ishibashi

Ah you're right TransportConnectJob has EndpointResultOverride but this has ServiceEndpointOverride.

Ack this is intended.

File net/socket/tcp_connect_job_connector.h
Line 115, Patchset 17 (Latest): int last_error_ = ERR_NAME_NOT_RESOLVED;
Kenichi Ishibashi . unresolved

optional: How about using std::optional<int> and return ERR_NAME_NOT_RESOLVED in DoObtainIPEndPoint() when no more IP endpoints to attempt? Mostly for putting logic and comment into a single place.

File net/socket/tcp_connect_job_connector.cc
Line 195, Patchset 1: if (parent_job_->websocket_endpoint_lock_manager()) {
mmenke . resolved

Note that this is on top of a CL that I sent to ricea@ that simplifies the WebSocket code needed in this CL. It's possible things will change as that review progresses, but I'll just keep this completely in sync with whatever we do there.

I don't intend to add any unit tests for this call. There are tests at the websocket layer, which pass when the feature is enabled. I may make them run with and without the feature when I actually wire things up, but am not too concerned about this.

Kenichi Ishibashi

Acknowledged

Line 236, Patchset 17 (Latest): if (error == ERR_NETWORK_IO_SUSPENDED) {
Kenichi Ishibashi . resolved

Oh I wasn't aware this logic (in the old TransportConnectJob). I probably want to add similar logic to HEv3, if we keep it.

File net/socket/tcp_connect_job_unittest.cc
Line 94, Patchset 17 (Latest): builder.set_ech_config_list({'?'});
Kenichi Ishibashi . unresolved

Could you add a comment the `?` value can be anything, not that important.

Line 239, Patchset 17 (Latest): // Use something othen than ERR_NAME_NOT_RESOLVED because that's the default
Kenichi Ishibashi . unresolved

other?

Line 249, Patchset 17 (Latest): // Use something othen than ERR_NAME_NOT_RESOLVED because that's the default
Kenichi Ishibashi . unresolved

ditt, other?

Line 396, Patchset 17 (Latest):// IP address, which should be enough for the job to connect and return a
Kenichi Ishibashi . unresolved

Should we reset ServiceEndpointRequest and mark DNS resolution completed successfully for this case? Or will the Job be expected to being destroyed immediately after the consumer takes the result?

Line 508, Patchset 17 (Latest): AddConnect(
Kenichi Ishibashi . unresolved

nit: Can we have a comment that the first endpoint fails.

Line 570, Patchset 17 (Latest): int service_endpoint;
Kenichi Ishibashi . unresolved

optional: service_endpint_index? (This is a bit cryptic to me, but I don't have a good idea to make it more easy to understand)

Line 789, Patchset 17 (Latest): // This will result in trying IPS in this order, since IPv4 and IPv6
Kenichi Ishibashi . unresolved

IPs ?

Line 831, Patchset 17 (Latest): // This will result in trying IPS in this order, since IPv4 and IPv6
Kenichi Ishibashi . unresolved

Ditto, IPs ?

Open in Gerrit

Related details

Attention is currently required from:
  • mmenke
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
    Gerrit-Change-Number: 7589439
    Gerrit-PatchSet: 17
    Gerrit-Owner: mmenke <mme...@chromium.org>
    Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
    Gerrit-Reviewer: mmenke <mme...@chromium.org>
    Gerrit-CC: Helmut Januschka <hel...@januschka.com>
    Gerrit-Attention: mmenke <mme...@chromium.org>
    Gerrit-Comment-Date: Fri, 20 Feb 2026 06:39:01 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    mmenke (Gerrit)

    unread,
    Feb 20, 2026, 12:37:19 PM (21 hours ago) Feb 20
    to Kenichi Ishibashi, Helmut Januschka, Chromium LUCI CQ, chromium...@chromium.org, net-r...@chromium.org

    mmenke voted and added 13 comments

    Votes added by mmenke

    Commit-Queue+2

    13 comments

    Patchset-level comments
    File-level comment, Patchset 17:
    mmenke . resolved

    Thanks, Kenichi! I'm going to go ahead and land this, happy to address any followup comments in future CLs.

    File net/socket/tcp_connect_job.h
    Line 175, Patchset 17: const ServiceEndpoint* FindServiceEndpoint(
    Kenichi Ishibashi . resolved

    std::optional<ServiceEndpoint> since we make a copy if we find available one?

    mmenke

    Not done. The method just below doesn't want a copy, it just wants to check if IPEndPoint is usable, which it does by checking if this returns a non-null value. We don't want/need to copy in that case.

    Line 135, Patchset 8: using IPEndPointInfo = base::expected<IPEndPoint, Error>;
    Kenichi Ishibashi . resolved

    (Just leaving comments for possible future changes)

    When we support HTTPS RR follow-up queries (alias and different target names), each "endpoint" may have different alpns and/or different SvcParams (e.g. ECH config). In the future, we may want to track attempted/attempting endpoint including these information, not just IPEndPoint.

    mmenke

    I assume we'd still want to connect before crypto ready, so we'd still be passing around raw IPEndpoints, though that does potentially lead to a new weird case: We have connections to non-crypto-ready IPs, but other IPs are crypto ready. What do we do?

    It may actually make sense to make a 3rd connection in that case, while keeping old connections around I guess?

    mmenke

    So, right now, what this class needs crypto ready for is to know two things (I think):

    1) We know the final value of `svcb_optional_`. This is the part I'm most familiar with, since it's dealt with directly by this ConnectJob, so it's what I've been associating with crypto ready.
    2) We know when we have enough information to let the SSL layer connect. This is actually what crypto ready is named after.

    If crypto ready information trickles in, when would we know enough to set `svcb_optional_`? I assume it would still have one value for the entire request, but not clear to me if we'd get it early or late. If it's late, we could presumably still complete before we have it, if we know an endpoint is crypto ready (and thus have a SVCB record for it).

    Kenichi Ishibashi

    To calculate `svcb_optional_` for different endpoints, we probably need to modify the ServiceEndpointRequest API first so that we can distinguish which endpoints are crypto ready and which endpoints are not crypto ready.

    I haven't really thought about what kind of interface would be best, maybe something like:
    ```
    class ServiceEndpointRequest {
    bool IsEndpointsCryptoReady(const ServiceEndpoint& endpoint) = 0;
    };
    ```

    or

    ```
    class ServiceEndpoint {
    bool endpoint_crypto_ready = false;
    };
    ```

    Not entirely sure about this. Let me loop hel...@januschka.com in since they proposed HTTPS follow-up queries.
    https://docs.google.com/document/d/1Xku49GjTNUccpuZtJnImWN90fJgX43d9_rH91vHs7wc/edit?usp=sharing

    helmut@: Note that we haven't decided we would like you to work on that. Just sharing information.

    mmenke

    Acknowledged

    File net/socket/tcp_connect_job_connector.h
    Line 115, Patchset 17: int last_error_ = ERR_NAME_NOT_RESOLVED;
    Kenichi Ishibashi . resolved

    optional: How about using std::optional<int> and return ERR_NAME_NOT_RESOLVED in DoObtainIPEndPoint() when no more IP endpoints to attempt? Mostly for putting logic and comment into a single place.

    mmenke

    Done

    File net/socket/tcp_connect_job_connector.cc
    Line 195, Patchset 1: if (parent_job_->websocket_endpoint_lock_manager()) {
    mmenke . resolved

    Note that this is on top of a CL that I sent to ricea@ that simplifies the WebSocket code needed in this CL. It's possible things will change as that review progresses, but I'll just keep this completely in sync with whatever we do there.

    I don't intend to add any unit tests for this call. There are tests at the websocket layer, which pass when the feature is enabled. I may make them run with and without the feature when I actually wire things up, but am not too concerned about this.

    Kenichi Ishibashi

    Acknowledged

    mmenke

    I've removed the WebSocket code, since that CL hasn't landed yet. I'll wire it up in another CL (Added TODO)

    File net/socket/tcp_connect_job_unittest.cc
    Line 94, Patchset 17: builder.set_ech_config_list({'?'});
    Kenichi Ishibashi . resolved

    Could you add a comment the `?` value can be anything, not that important.

    mmenke

    Done

    Line 239, Patchset 17: // Use something othen than ERR_NAME_NOT_RESOLVED because that's the default
    Kenichi Ishibashi . resolved

    other?

    mmenke

    Done

    Line 249, Patchset 17: // Use something othen than ERR_NAME_NOT_RESOLVED because that's the default
    Kenichi Ishibashi . resolved

    ditt, other?

    mmenke

    Done

    Line 396, Patchset 17:// IP address, which should be enough for the job to connect and return a
    Kenichi Ishibashi . resolved

    Should we reset ServiceEndpointRequest and mark DNS resolution completed successfully for this case? Or will the Job be expected to being destroyed immediately after the consumer takes the result?

    mmenke

    If we destroy that request, we'll need to cache the ServiceEndpoint, and if we want to avoid copying it twice, GetServiceEndpoint() would need to become TakeServiceEndpoint(), and std::move() it. There's a TODO suggesting we do that.

    Anyhow, the job not being deleted immediately in this case is the reason for the `is_done_` changes in the DNS callbacks. I think this is definitely something worth investigating further, but not in this CL.

    Line 508, Patchset 17: AddConnect(
    Kenichi Ishibashi . resolved

    nit: Can we have a comment that the first endpoint fails.

    mmenke

    Done

    Line 570, Patchset 17: int service_endpoint;
    Kenichi Ishibashi . resolved

    optional: service_endpint_index? (This is a bit cryptic to me, but I don't have a good idea to make it more easy to understand)

    mmenke

    Done (+comment)

    Line 789, Patchset 17: // This will result in trying IPS in this order, since IPv4 and IPv6
    Kenichi Ishibashi . resolved

    IPs ?

    mmenke

    Done

    Line 831, Patchset 17: // This will result in trying IPS in this order, since IPv4 and IPv6
    Kenichi Ishibashi . resolved

    Ditto, IPs ?

    mmenke

    Done

    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
      Gerrit-Change-Number: 7589439
      Gerrit-PatchSet: 18
      Gerrit-Owner: mmenke <mme...@chromium.org>
      Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
      Gerrit-Reviewer: mmenke <mme...@chromium.org>
      Gerrit-CC: Helmut Januschka <hel...@januschka.com>
      Gerrit-Comment-Date: Fri, 20 Feb 2026 17:37:13 +0000
      satisfied_requirement
      open
      diffy

      Chromium LUCI CQ (Gerrit)

      unread,
      Feb 20, 2026, 1:24:15 PM (20 hours ago) Feb 20
      to Kenichi Ishibashi, Helmut Januschka, chromium...@chromium.org, net-r...@chromium.org

      Chromium LUCI CQ submitted the change with unreviewed changes

      Unreviewed changes

      17 is the latest approved patch-set.
      The change was submitted with unreviewed changes in the following files:

      ```
      The name of the file: net/socket/tcp_connect_job.cc
      Insertions: 5, Deletions: 3.

      The diff is too large to show. Please review the diff.
      ```
      ```
      The name of the file: net/socket/tcp_connect_job_connector.cc
      Insertions: 6, Deletions: 14.

      The diff is too large to show. Please review the diff.
      ```
      ```
      The name of the file: net/socket/tcp_connect_job_unittest.cc
      Insertions: 11, Deletions: 6.

      The diff is too large to show. Please review the diff.
      ```
      ```
      The name of the file: net/socket/tcp_connect_job.h
      Insertions: 4, Deletions: 4.

      The diff is too large to show. Please review the diff.
      ```
      ```
      The name of the file: net/socket/tcp_connect_job_connector.h
      Insertions: 1, Deletions: 1.

      The diff is too large to show. Please review the diff.
      ```

      Change information

      Commit message:
      Initial TcpConnectJob implementation.

      This is the first CL for a relatively simple upgrade of the TCP
      connection establishment logic to Happy Eyeballs v2 + HTTPS record
      awareness.

      The idea is to establish IPv4/v6 connections as the component DNS
      requests complete, but to respect HTTPS records, and respect
      ServiceEndpoint priority as best we can.

      This CL only makes one connection at a time, alternating v4 and v6
      addresses, though a followup CL will run two at once if the initial
      connection attempt takes too long.

      There was a fare bit pruned from a full CL, so some comments may
      reference code not included in this initial CL.
      Bug: 484073410
      Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
      Reviewed-by: Kenichi Ishibashi <ba...@chromium.org>
      Commit-Queue: mmenke <mme...@chromium.org>
      Cr-Commit-Position: refs/heads/main@{#1587937}
      Files:
      • M net/BUILD.gn
      • A net/socket/tcp_connect_job.cc
      • A net/socket/tcp_connect_job.h
      • A net/socket/tcp_connect_job_connector.cc
      • A net/socket/tcp_connect_job_connector.h
      • A net/socket/tcp_connect_job_unittest.cc
      Change size: XL
      Delta: 6 files changed, 2258 insertions(+), 0 deletions(-)
      Branch: refs/heads/main
      Submit Requirements:
      • requirement satisfiedCode-Review: +1 by Kenichi Ishibashi
      Open in Gerrit
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: merged
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I5fad29f3d3b7c13a444d7bd5ee5ac01cca653517
      Gerrit-Change-Number: 7589439
      Gerrit-PatchSet: 19
      Gerrit-Owner: mmenke <mme...@chromium.org>
      Gerrit-Reviewer: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
      Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
      Gerrit-Reviewer: mmenke <mme...@chromium.org>
      open
      diffy
      satisfied_requirement
      Reply all
      Reply to author
      Forward
      0 new messages