diff --git a/docs/configuration/inbound/mieru.md b/docs/configuration/inbound/mieru.md index 5c422005..88aa7250 100644 --- a/docs/configuration/inbound/mieru.md +++ b/docs/configuration/inbound/mieru.md @@ -19,6 +19,7 @@ icon: material/new-box } ], "traffic_pattern": "GgQIARAK", + "mtu": 1400 } ``` @@ -47,3 +48,7 @@ A base64 string to fine tune network behavior. #### user_hint_is_mandatory If proxy client doesn't sent user hint, proxy server will refuse the connection. + +#### mtu + +Maximum transmission unit of L2 payload. Only applies to UDP transport egress traffic. diff --git a/docs/configuration/inbound/mieru.zh.md b/docs/configuration/inbound/mieru.zh.md index a389db27..cfd9dc6f 100644 --- a/docs/configuration/inbound/mieru.zh.md +++ b/docs/configuration/inbound/mieru.zh.md @@ -19,6 +19,7 @@ icon: material/new-box } ], "traffic_pattern": "GgQIARAK", + "mtu": 1400 } ``` @@ -47,3 +48,7 @@ icon: material/new-box #### user_hint_is_mandatory 客户端若不发送用户提示,代理服务器将拒绝连接。 + +#### mtu + +L2 载荷的最大传输单元。仅适用于 UDP 传输方式的出站流量。 diff --git a/docs/configuration/outbound/mieru.md b/docs/configuration/outbound/mieru.md index 22851fcb..00c27c79 100644 --- a/docs/configuration/outbound/mieru.md +++ b/docs/configuration/outbound/mieru.md @@ -20,6 +20,8 @@ icon: material/new-box "password": "hjkl", "multiplexing": "MULTIPLEXING_LOW", "traffic_pattern": "GgQIARAK", + "mtu": 1400, + "handshake_mode": "HANDSHAKE_STANDARD", ... // Dial Fields } @@ -71,6 +73,14 @@ Multiplexing level. Supported values are `MULTIPLEXING_OFF`, `MULTIPLEXING_LOW`, A base64 string to fine tune network behavior. +#### mtu + +Maximum transmission unit of L2 payload. Only applies to UDP transport egress traffic. + +#### handshake_mode + +Handshake mode when the client opens a connection. Allowed values are `HANDSHAKE_STANDARD` (1-RTT, wait for the proxy server to establish the connection to the destination before sending payload) and `HANDSHAKE_NO_WAIT` (0-RTT, send payload together with the connection to the proxy server). + ### Dial Fields See [Dial Fields](/configuration/shared/dial/) for details. diff --git a/docs/configuration/outbound/mieru.zh.md b/docs/configuration/outbound/mieru.zh.md index 9fdb52fa..cd987086 100644 --- a/docs/configuration/outbound/mieru.zh.md +++ b/docs/configuration/outbound/mieru.zh.md @@ -20,6 +20,8 @@ icon: material/new-box "password": "hjkl", "multiplexing": "MULTIPLEXING_LOW", "traffic_pattern": "GgQIARAK", + "mtu": 1400, + "handshake_mode": "HANDSHAKE_STANDARD", ... // 拨号字段 } @@ -71,6 +73,14 @@ mieru 密码。 一个 base64 字符串用于微调网络行为。 +#### mtu + +L2 载荷的最大传输单元。仅适用于 UDP 传输方式的出站流量。 + +#### handshake_mode + +客户端建立连接时的握手模式。可设为 `HANDSHAKE_STANDARD`(1-RTT,客户端等待代理服务器建立到目标地址的连接后再发送载荷)或 `HANDSHAKE_NO_WAIT`(0-RTT,客户端在连接代理服务器的同时发送载荷)。 + ### 拨号字段 参阅 [拨号字段](/zh/configuration/shared/dial/)。 diff --git a/examples/mieru/client.json b/examples/mieru/client.json index d919e26e..c631bb21 100644 --- a/examples/mieru/client.json +++ b/examples/mieru/client.json @@ -36,7 +36,10 @@ // valid: MULTIPLEXING_DEFAULT / MULTIPLEXING_OFF / MULTIPLEXING_LOW // MULTIPLEXING_MIDDLE / MULTIPLEXING_HIGH "multiplexing": "MULTIPLEXING_LOW", - "traffic_pattern": "GgQIARAK" + "traffic_pattern": "GgQIARAK", + "mtu": 1400, + // valid: HANDSHAKE_DEFAULT / HANDSHAKE_STANDARD / HANDSHAKE_NO_WAIT + "handshake_mode": "HANDSHAKE_STANDARD" } ], "route": { diff --git a/examples/mieru/server.json b/examples/mieru/server.json index f147835e..5cdbd58d 100644 --- a/examples/mieru/server.json +++ b/examples/mieru/server.json @@ -17,7 +17,8 @@ "password": "password" } ], - "traffic_pattern": "GgQIARAK" + "traffic_pattern": "GgQIARAK", + "mtu": 1400 } ], "outbounds": [ diff --git a/option/mieru.go b/option/mieru.go index e666cb2d..598824d4 100644 --- a/option/mieru.go +++ b/option/mieru.go @@ -11,6 +11,8 @@ type MieruOutboundOptions struct { Password string `json:"password,omitempty"` Multiplexing string `json:"multiplexing,omitempty"` TrafficPattern string `json:"traffic_pattern,omitempty"` + MTU uint32 `json:"mtu,omitempty"` + HandshakeMode string `json:"handshake_mode,omitempty"` } type MieruInboundOptions struct { @@ -20,6 +22,7 @@ type MieruInboundOptions struct { Transport string `json:"transport,omitempty"` TrafficPattern string `json:"traffic_pattern,omitempty"` UserHintIsMandatory bool `json:"user_hint_is_mandatory,omitempty"` + MTU uint32 `json:"mtu,omitempty"` } type MieruUser struct { diff --git a/protocol/mieru/inbound.go b/protocol/mieru/inbound.go index 7b64aec2..372cd336 100644 --- a/protocol/mieru/inbound.go +++ b/protocol/mieru/inbound.go @@ -309,13 +309,17 @@ func buildMieruServerConfig(_ context.Context, options option.MieruInboundOption UserHintIsMandatory: proto.Bool(true), } } + config := &mierupb.ServerConfig{ + PortBindings: portBindings, + Users: users, + TrafficPattern: trafficPattern, + AdvancedSettings: advancedSettings, + } + if options.MTU != 0 { + config.Mtu = proto.Int32(int32(options.MTU)) + } return &mieruserver.ServerConfig{ - Config: &mierupb.ServerConfig{ - PortBindings: portBindings, - Users: users, - TrafficPattern: trafficPattern, - AdvancedSettings: advancedSettings, - }, + Config: config, }, userNames, nil } diff --git a/protocol/mieru/outbound.go b/protocol/mieru/outbound.go index efd98cb5..6176fe0f 100644 --- a/protocol/mieru/outbound.go +++ b/protocol/mieru/outbound.go @@ -235,6 +235,12 @@ func buildMieruClientConfig(options option.MieruOutboundOptions, dialer mieruDia Level: mierupb.MultiplexingLevel(multiplexing).Enum(), } } + if options.MTU != 0 { + config.Profile.Mtu = proto.Int32(int32(options.MTU)) + } + if handshakeMode, ok := mierupb.HandshakeMode_value[options.HandshakeMode]; ok { + config.Profile.HandshakeMode = mierupb.HandshakeMode(handshakeMode).Enum() + } if options.TrafficPattern != "" { trafficPattern, _ := mierutp.Decode(options.TrafficPattern) config.Profile.TrafficPattern = trafficPattern @@ -278,6 +284,11 @@ func validateMieruOptions(options option.MieruOutboundOptions) error { return fmt.Errorf("invalid multiplexing level: %s", options.Multiplexing) } } + if options.HandshakeMode != "" { + if _, ok := mierupb.HandshakeMode_value[options.HandshakeMode]; !ok { + return fmt.Errorf("invalid handshake mode: %s", options.HandshakeMode) + } + } if options.TrafficPattern != "" { trafficPattern, err := mierutp.Decode(options.TrafficPattern) if err != nil {