Skip to content

feat: allow mapping multiple domain names to single ip #763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

LostAttractor
Copy link
Contributor

@LostAttractor LostAttractor commented Feb 21, 2025

Background

当前dae通过观测dns请求来实现domain的路由,例如观测到google.com的地址为46.82.174.69,则内核部分会将46.82.174.69当作google.com处理,并且用户态会直接计算每条domain规则的匹配结果并直接注入

但假设一种情况,api.bilibili.comcm.bilibili.com均使用ip 61.240.206.12,dae会将61.240.206.12视为最后一次dns查询时的域名,并通过将ttl设置为0并期待每次产生连接前都产生一次dns查询

不过假如客户端完全不尊重ttl,那么一切就都乱套了,例如希望对api.bilibili.comcm.bilibili.com应用不同的路由,那么这将完全不工作

本PR设想了一种全新的方法,完全不依赖TTL,即如果api.bilibili.comcm.bilibili.com具有相同的路由(即,同时匹配同一个domain规则),则直接路由61.240.206.12,否则则强制跳入用户态依赖sniff进行重新路由

Checklist

目前还非常粗糙,需要充分测试

Full Changelogs

  • feat: allow mapping multiple domain names to single ip

Issue Reference

Closes #[issue number]

Test Result

Copy link
Member

@jschwinger233 jschwinger233 left a comment

Choose a reason for hiding this comment

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

bpf part lgtm.

但我还是更建议使用 bit field

            volatile u8 goodsubrule : 1;
            volatile u8 badrule     : 1;
            volatile u8 must        : 1;
            u8 isdns                : 1;
            unused : 4;

这样有更明确的 padding 而不会造成结构体空洞。空洞 + llvm 优化 是大量 bpf verifier 报错之源。

(以及为什么要用 volatile?删掉有影响吗?)

Copy link
Member

@jschwinger233 jschwinger233 left a comment

Choose a reason for hiding this comment

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

Lint 挂了,你在混用 tab 和 space。

@LostAttractor
Copy link
Contributor Author

bpf part lgtm.

但我还是更建议使用 bit field

            volatile u8 goodsubrule : 1;
            volatile u8 badrule     : 1;
            volatile u8 must        : 1;
            u8 isdns                : 1;
            unused : 4;

这样有更明确的 padding 而不会造成结构体空洞。空洞 + llvm 优化 是大量 bpf verifier 报错之源。

(以及为什么要用 volatile?删掉有影响吗?)

volatile 是因为原本就这么写了,我其实不知道这意味着什么

@LostAttractor
Copy link
Contributor Author

Lint 挂了,你在混用 tab 和 space。

已经修复

Copy link
Contributor

@dae-prow dae-prow bot left a comment

Choose a reason for hiding this comment

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

🧪 Since the PR has been fully tested, please consider merging it.

Copy link
Member

@jschwinger233 jschwinger233 left a comment

Choose a reason for hiding this comment

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

bpf parts lgtm

(domain_routing->bitmap[index / 32] >> (index % 32)) & 1)
ctx->isdns_must_goodsubrule_badrule |= 0b10;
(domain_routing->bitmap[index / 32] >> (index % 32)) & 1) {
// All domains mapeed by the current IP address are matched.
Copy link
Member

Choose a reason for hiding this comment

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

nit: typo mapeed

Copy link
Member

@jschwinger233 jschwinger233 left a comment

Choose a reason for hiding this comment

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

看了一下用户态的代码,有一些小疑问 🙏

@@ -123,6 +123,9 @@ func (m *RoutingMatcher) Match(
// Tail of a rule (line).
// Decide whether to hit.
if !badRule {
if outbound == consts.OutboundControlPlaneRouting {
continue
}
Copy link
Member

Choose a reason for hiding this comment

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

我记得这个函数要和 bpf 的逻辑一致,这个修改在 bpf 里貌似没有?

if !exists {
newBumpMap = make([]uint32, consts.MaxMatchSetLen)
}
for index := 0; index < consts.MaxMatchSetLen; index++ {
Copy link
Member

Choose a reason for hiding this comment

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

似乎有点浪费 cpu 了,大部分用户的规则都不会超过 100 条吧,这里 MaxMatchSetLen 是 1024,可以做个短路 break

// jump to control plane.
need_control_plane_routing = true;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

这一段逻辑也应该更新到 routing_matcher_userspace.go:Match() ?

@@ -833,7 +857,7 @@ static int route_loop_cb(__u32 index, void *data)
} else {
bool must = ctx->must || match_set->must;

if (!must && ctx->isdns) {
if ((!must && ctx->isdns) || need_control_plane_routing) {
Copy link
Member

Choose a reason for hiding this comment

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

ditto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants