Skip to content

Commit d1e2c23

Browse files
authored
Add RRPIT - Rapid Reliable Packet Interactive Transport (#3658)
* Add rrpit(unreleased) transport * rrpit(unreleased) transport: boost reconstruction for the front lane * rrpit(unreleased) transport: avoid blocking delivery of packets with smux packet reordering * rrpit(unreleased) transport: add dual channel with differential prioritization * rrpit(unreleased) transport: add remoteMaxDataShardsPerLane * rrpit(unreleased) transport: add remoteMaxDataShardsPerLane(fix) * rrpit(unreleased) transport: add auto-reconnect for transport connection * rrpit(unreleased) transport: add auto-reconnect for transport connection * rrpit(unreleased) transport: update tests * rrpit(unreleased) transport: limit frame size for framed packet write closer * rrpit(unreleased) transport: remove packet length wrapper * rrpit(unreleased) transport: update go mod * rrpit(unreleased) transport: update dtls error propagation * rrpit(unreleased) transport: update broken tests * rrpit(unreleased) transport: fix deadlock when closing persistent channel * rrpit(unreleased) transport: add server disconnection detection for persistent connection * rrpit(unreleased) transport: fix broken lints * rrpit(unreleased) transport: fix broken lints * rrpit(unreleased) transport: fix broken lints * rrpit(unreleased) transport: fix broken lints * rrpit(unreleased) transport: fix broken lints
1 parent cf7577f commit d1e2c23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+16524
-113
lines changed

app/dispatcher/default.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,19 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
313313
}
314314
} else if d.router != nil {
315315
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
316+
if routeWithAttributes, ok := route.(interface{ GetSessionAttributes() map[string]string }); ok {
317+
attrs := routeWithAttributes.GetSessionAttributes()
318+
if len(attrs) > 0 {
319+
content := session.ContentFromContext(ctx)
320+
if content == nil {
321+
content = new(session.Content)
322+
ctx = session.ContextWithContent(ctx, content)
323+
}
324+
for key, value := range attrs {
325+
content.SetAttribute(key, value)
326+
}
327+
}
328+
}
316329
tag := route.GetOutboundTag()
317330
if h := d.ohm.GetHandler(tag); h != nil {
318331
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))

app/router/config.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ import (
1818
)
1919

2020
type Rule struct {
21-
Tag string
22-
Balancer *Balancer
23-
Condition Condition
21+
Tag string
22+
Balancer *Balancer
23+
Condition Condition
24+
SetAttributes []*SetAttribute
2425
}
2526

2627
func (r *Rule) GetTag() (string, error) {

app/router/config.pb.go

Lines changed: 176 additions & 94 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/router/config.proto

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import "common/net/network.proto";
1212
import "common/protoext/extensions.proto";
1313
import "app/router/routercommon/common.proto";
1414

15+
message SetAttribute {
16+
string key = 1;
17+
string value = 2;
18+
}
1519

1620
message RoutingRule {
1721
oneof target_tag {
@@ -66,6 +70,8 @@ message RoutingRule {
6670

6771
string domain_matcher = 17;
6872

73+
repeated SetAttribute set_attribute = 18;
74+
6975
// geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.
7076
repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;
7177
}
@@ -178,6 +184,8 @@ message SimplifiedRoutingRule {
178184

179185
string domain_matcher = 17;
180186

187+
repeated SetAttribute set_attribute = 18;
188+
181189
// geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.
182190
repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;
183191
}
@@ -189,4 +197,4 @@ message SimplifiedConfig {
189197
DomainStrategy domain_strategy = 1;
190198
repeated SimplifiedRoutingRule rule = 2;
191199
repeated BalancingRule balancing_rule = 3;
192-
}
200+
}

app/router/router.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type Route struct {
2929
routing.Context
3030
outboundGroupTags []string
3131
outboundTag string
32+
sessionAttributes map[string]string
3233
}
3334

3435
// Init initializes the Router.
@@ -53,8 +54,9 @@ func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm out
5354
return err
5455
}
5556
rr := &Rule{
56-
Condition: cond,
57-
Tag: rule.GetTag(),
57+
Condition: cond,
58+
Tag: rule.GetTag(),
59+
SetAttributes: rule.GetSetAttribute(),
5860
}
5961
btag := rule.GetBalancingTag()
6062
if len(btag) > 0 {
@@ -80,7 +82,20 @@ func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) {
8082
if err != nil {
8183
return nil, err
8284
}
83-
return &Route{Context: ctx, outboundTag: tag}, nil
85+
route := &Route{Context: ctx, outboundTag: tag}
86+
if len(rule.SetAttributes) > 0 {
87+
route.sessionAttributes = make(map[string]string, len(rule.SetAttributes))
88+
for _, attr := range rule.SetAttributes {
89+
if attr == nil || attr.Key == "" {
90+
continue
91+
}
92+
route.sessionAttributes[attr.Key] = attr.Value
93+
}
94+
if len(route.sessionAttributes) == 0 {
95+
route.sessionAttributes = nil
96+
}
97+
}
98+
return route, nil
8499
}
85100

86101
func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {
@@ -140,6 +155,17 @@ func (r *Route) GetOutboundTag() string {
140155
return r.outboundTag
141156
}
142157

158+
func (r *Route) GetSessionAttributes() map[string]string {
159+
if r == nil || len(r.sessionAttributes) == 0 {
160+
return nil
161+
}
162+
out := make(map[string]string, len(r.sessionAttributes))
163+
for key, value := range r.sessionAttributes {
164+
out[key] = value
165+
}
166+
return out
167+
}
168+
143169
func init() {
144170
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
145171
r := new(Router)
@@ -242,6 +268,7 @@ func init() {
242268
rule.Networks = v.Networks.GetNetwork()
243269
rule.Protocol = v.Protocol
244270
rule.Attributes = v.Attributes
271+
rule.SetAttribute = append(rule.SetAttribute, v.SetAttribute...)
245272
rule.UserEmail = v.UserEmail
246273
rule.InboundTag = v.InboundTag
247274
rule.DomainMatcher = v.DomainMatcher

app/router/router_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,50 @@ func TestSimpleRouter(t *testing.T) {
5454
}
5555
}
5656

57+
func TestRouteSetAttribute(t *testing.T) {
58+
config := &Config{
59+
Rule: []*RoutingRule{
60+
{
61+
TargetTag: &RoutingRule_Tag{
62+
Tag: "test",
63+
},
64+
Networks: []net.Network{net.Network_TCP},
65+
SetAttribute: []*SetAttribute{
66+
{
67+
Key: "rrpitSessionClass",
68+
Value: "background",
69+
},
70+
},
71+
},
72+
},
73+
}
74+
75+
mockCtl := gomock.NewController(t)
76+
defer mockCtl.Finish()
77+
78+
mockDNS := mocks.NewDNSClient(mockCtl)
79+
mockOhm := mocks.NewOutboundManager(mockCtl)
80+
mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
81+
82+
r := new(Router)
83+
common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
84+
Manager: mockOhm,
85+
HandlerSelector: mockHs,
86+
}, nil))
87+
88+
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
89+
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
90+
common.Must(err)
91+
attrRoute, ok := route.(interface{ GetSessionAttributes() map[string]string })
92+
if !ok {
93+
t.Fatal("route does not expose session attributes")
94+
}
95+
attrs := attrRoute.GetSessionAttributes()
96+
if attrs["rrpitSessionClass"] != "background" {
97+
t.Fatalf("unexpected session attribute map: %#v", attrs)
98+
}
99+
}
100+
57101
func TestSimpleBalancer(t *testing.T) {
58102
config := &Config{
59103
Rule: []*RoutingRule{

common/net/abstactOutbount/errors.generated.go renamed to common/net/abstactOutbound/errors.generated.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package abstactOutbount
1+
package abstactOutbound
22

33
import "github.com/v2fly/v2ray-core/v5/common/errors"
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package abstactOutbount
1+
package abstactOutbound
22

33
//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
44

config.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ require (
1818
github.com/gorilla/websocket v1.5.3
1919
github.com/improbable-eng/grpc-web v0.15.0
2020
github.com/jhump/protoreflect v1.18.0
21+
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
2122
github.com/miekg/dns v1.1.72
2223
github.com/mustafaturan/bus v1.0.2
2324
github.com/pelletier/go-toml v1.9.5
24-
github.com/pion/dtls/v2 v2.2.12
25+
github.com/pion/dtls/v3 v3.0.11
2526
github.com/pion/stun/v3 v3.1.1
2627
github.com/pion/transport/v2 v2.2.10
2728
github.com/pires/go-proxyproto v0.11.0
@@ -36,6 +37,8 @@ require (
3637
github.com/v2fly/struc v0.0.0-20241227015403-8e8fa1badfd6
3738
github.com/vincent-petithory/dataurl v1.0.0
3839
github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432
40+
github.com/xssnick/raptorq v1.3.0
41+
github.com/xtaci/smux v1.5.24
3942
go.starlark.net v0.0.0-20230612165344-9532f5667272
4043
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35
4144
golang.org/x/crypto v0.49.0
@@ -71,10 +74,9 @@ require (
7174
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
7275
github.com/klauspost/reedsolomon v1.11.7 // indirect
7376
github.com/leodido/go-urn v1.4.0 // indirect
74-
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
7577
github.com/mustafaturan/monoton v1.0.0 // indirect
7678
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
77-
github.com/pion/dtls/v3 v3.0.11 // indirect
79+
github.com/pion/dtls/v2 v2.2.12 // indirect
7880
github.com/pion/logging v0.2.4 // indirect
7981
github.com/pion/randutil v0.1.0 // indirect
8082
github.com/pion/sctp v1.8.7 // indirect
@@ -87,7 +89,6 @@ require (
8789
github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect
8890
github.com/stretchr/objx v0.5.2 // indirect
8991
github.com/wlynxg/anet v0.0.5 // indirect
90-
github.com/xtaci/smux v1.5.24 // indirect
9192
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
9293
golang.org/x/mod v0.33.0 // indirect
9394
golang.org/x/text v0.35.0 // indirect

0 commit comments

Comments
 (0)