Skip to content

Commit 1dc4155

Browse files
committed
feat: inbound's port can use ports format
1 parent d81c19a commit 1dc4155

15 files changed

+255
-149
lines changed

docs/config.yaml

+12-12
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ sub-rules:
10961096
listeners:
10971097
- name: socks5-in-1
10981098
type: socks
1099-
port: 10808
1099+
port: 10808 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11001100
#listen: 0.0.0.0 # 默认监听 0.0.0.0
11011101
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11021102
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理
@@ -1107,7 +1107,7 @@ listeners:
11071107

11081108
- name: http-in-1
11091109
type: http
1110-
port: 10809
1110+
port: 10809 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11111111
listen: 0.0.0.0
11121112
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11131113
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1117,7 +1117,7 @@ listeners:
11171117

11181118
- name: mixed-in-1
11191119
type: mixed # HTTP(S) 和 SOCKS 代理混合
1120-
port: 10810
1120+
port: 10810 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11211121
listen: 0.0.0.0
11221122
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11231123
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1128,22 +1128,22 @@ listeners:
11281128

11291129
- name: reidr-in-1
11301130
type: redir
1131-
port: 10811
1131+
port: 10811 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11321132
listen: 0.0.0.0
11331133
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11341134
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
11351135

11361136
- name: tproxy-in-1
11371137
type: tproxy
1138-
port: 10812
1138+
port: 10812 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11391139
listen: 0.0.0.0
11401140
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11411141
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
11421142
# udp: false # 默认 true
11431143

11441144
- name: shadowsocks-in-1
11451145
type: shadowsocks
1146-
port: 10813
1146+
port: 10813 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11471147
listen: 0.0.0.0
11481148
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11491149
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1152,7 +1152,7 @@ listeners:
11521152

11531153
- name: vmess-in-1
11541154
type: vmess
1155-
port: 10814
1155+
port: 10814 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11561156
listen: 0.0.0.0
11571157
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11581158
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1176,7 +1176,7 @@ listeners:
11761176

11771177
- name: tuic-in-1
11781178
type: tuic
1179-
port: 10815
1179+
port: 10815 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
11801180
listen: 0.0.0.0
11811181
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
11821182
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1196,7 +1196,7 @@ listeners:
11961196

11971197
- name: tunnel-in-1
11981198
type: tunnel
1199-
port: 10816
1199+
port: 10816 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
12001200
listen: 0.0.0.0
12011201
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
12021202
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1205,7 +1205,7 @@ listeners:
12051205

12061206
- name: vless-in-1
12071207
type: vless
1208-
port: 10817
1208+
port: 10817 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
12091209
listen: 0.0.0.0
12101210
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
12111211
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)
@@ -1230,7 +1230,7 @@ listeners:
12301230

12311231
- name: anytls-in-1
12321232
type: anytls
1233-
port: 10818
1233+
port: 10818 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
12341234
listen: 0.0.0.0
12351235
users:
12361236
username1: password1
@@ -1242,7 +1242,7 @@ listeners:
12421242

12431243
- name: trojan-in-1
12441244
type: trojan
1245-
port: 10819
1245+
port: 10819 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503
12461246
listen: 0.0.0.0
12471247
# rule: sub-rule-name1 # 默认使用 rules,如果未找到 sub-rule 则直接使用 rules
12481248
# proxy: proxy # 如果不为空则直接将该入站流量交由指定 proxy 处理 (当 proxy 不为空时,这里的 proxy 名称必须合法,否则会出错)

listener/inbound/anytls.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package inbound
22

33
import (
4+
"strings"
5+
46
C "github.com/metacubex/mihomo/constant"
57
"github.com/metacubex/mihomo/listener/anytls"
68
LC "github.com/metacubex/mihomo/listener/config"
@@ -52,12 +54,13 @@ func (v *AnyTLS) Config() C.InboundConfig {
5254

5355
// Address implements constant.InboundListener
5456
func (v *AnyTLS) Address() string {
57+
var addrList []string
5558
if v.l != nil {
5659
for _, addr := range v.l.AddrList() {
57-
return addr.String()
60+
addrList = append(addrList, addr.String())
5861
}
5962
}
60-
return ""
63+
return strings.Join(addrList, ",")
6164
}
6265

6366
// Listen implements constant.InboundListener

listener/inbound/base.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import (
55
"net"
66
"net/netip"
77
"strconv"
8+
"strings"
89

910
"github.com/metacubex/mihomo/adapter/inbound"
11+
"github.com/metacubex/mihomo/common/utils"
1012
C "github.com/metacubex/mihomo/constant"
1113
)
1214

@@ -15,7 +17,7 @@ type Base struct {
1517
name string
1618
specialRules string
1719
listenAddr netip.Addr
18-
port int
20+
ports utils.IntRanges[uint16]
1921
}
2022

2123
func NewBase(options *BaseOption) (*Base, error) {
@@ -26,11 +28,15 @@ func NewBase(options *BaseOption) (*Base, error) {
2628
if err != nil {
2729
return nil, err
2830
}
31+
ports, err := utils.NewUnsignedRanges[uint16](options.Port)
32+
if err != nil {
33+
return nil, err
34+
}
2935
return &Base{
3036
name: options.Name(),
3137
listenAddr: addr,
3238
specialRules: options.SpecialRules,
33-
port: options.Port,
39+
ports: ports,
3440
config: options,
3541
}, nil
3642
}
@@ -57,7 +63,15 @@ func (b *Base) Name() string {
5763

5864
// RawAddress implements constant.InboundListener
5965
func (b *Base) RawAddress() string {
60-
return net.JoinHostPort(b.listenAddr.String(), strconv.Itoa(int(b.port)))
66+
if len(b.ports) == 0 {
67+
return net.JoinHostPort(b.listenAddr.String(), "0")
68+
}
69+
address := make([]string, 0, len(b.ports))
70+
b.ports.Range(func(port uint16) bool {
71+
address = append(address, net.JoinHostPort(b.listenAddr.String(), strconv.Itoa(int(port))))
72+
return true
73+
})
74+
return strings.Join(address, ",")
6175
}
6276

6377
// Listen implements constant.InboundListener
@@ -74,7 +88,7 @@ var _ C.InboundListener = (*Base)(nil)
7488
type BaseOption struct {
7589
NameStr string `inbound:"name"`
7690
Listen string `inbound:"listen,omitempty"`
77-
Port int `inbound:"port,omitempty"`
91+
Port string `inbound:"port,omitempty"`
7892
SpecialRules string `inbound:"rule,omitempty"`
7993
SpecialProxy string `inbound:"proxy,omitempty"`
8094
}

listener/inbound/http.go

+25-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package inbound
22

33
import (
4+
"errors"
5+
"fmt"
6+
"strings"
7+
48
C "github.com/metacubex/mihomo/constant"
59
"github.com/metacubex/mihomo/listener/http"
610
"github.com/metacubex/mihomo/log"
@@ -18,7 +22,7 @@ func (o HTTPOption) Equal(config C.InboundConfig) bool {
1822
type HTTP struct {
1923
*Base
2024
config *HTTPOption
21-
l *http.Listener
25+
l []*http.Listener
2226
}
2327

2428
func NewHTTP(options *HTTPOption) (*HTTP, error) {
@@ -39,24 +43,37 @@ func (h *HTTP) Config() C.InboundConfig {
3943

4044
// Address implements constant.InboundListener
4145
func (h *HTTP) Address() string {
42-
return h.l.Address()
46+
var addrList []string
47+
for _, l := range h.l {
48+
addrList = append(addrList, l.Address())
49+
}
50+
return strings.Join(addrList, ",")
4351
}
4452

4553
// Listen implements constant.InboundListener
4654
func (h *HTTP) Listen(tunnel C.Tunnel) error {
47-
var err error
48-
h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuthStore(), h.Additions()...)
49-
if err != nil {
50-
return err
55+
for _, addr := range strings.Split(h.RawAddress(), ",") {
56+
l, err := http.NewWithAuthenticator(addr, tunnel, h.config.Users.GetAuthStore(), h.Additions()...)
57+
if err != nil {
58+
return err
59+
}
60+
h.l = append(h.l, l)
5161
}
5262
log.Infoln("HTTP[%s] proxy listening at: %s", h.Name(), h.Address())
5363
return nil
5464
}
5565

5666
// Close implements constant.InboundListener
5767
func (h *HTTP) Close() error {
58-
if h.l != nil {
59-
return h.l.Close()
68+
var errs []error
69+
for _, l := range h.l {
70+
err := l.Close()
71+
if err != nil {
72+
errs = append(errs, fmt.Errorf("close tcp listener %s err: %w", l.Address(), err))
73+
}
74+
}
75+
if len(errs) > 0 {
76+
return errors.Join(errs...)
6077
}
6178
return nil
6279
}

listener/inbound/hysteria2.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package inbound
22

33
import (
4+
"strings"
5+
46
C "github.com/metacubex/mihomo/constant"
57
LC "github.com/metacubex/mihomo/listener/config"
68
"github.com/metacubex/mihomo/listener/sing_hysteria2"
@@ -83,12 +85,13 @@ func (t *Hysteria2) Config() C.InboundConfig {
8385

8486
// Address implements constant.InboundListener
8587
func (t *Hysteria2) Address() string {
88+
var addrList []string
8689
if t.l != nil {
8790
for _, addr := range t.l.AddrList() {
88-
return addr.String()
91+
addrList = append(addrList, addr.String())
8992
}
9093
}
91-
return ""
94+
return strings.Join(addrList, ",")
9295
}
9396

9497
// Listen implements constant.InboundListener

listener/inbound/mixed.go

+32-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package inbound
22

33
import (
4+
"errors"
45
"fmt"
6+
"strings"
57

68
C "github.com/metacubex/mihomo/constant"
79
"github.com/metacubex/mihomo/log"
@@ -23,8 +25,8 @@ func (o MixedOption) Equal(config C.InboundConfig) bool {
2325
type Mixed struct {
2426
*Base
2527
config *MixedOption
26-
l *mixed.Listener
27-
lUDP *socks.UDPListener
28+
l []*mixed.Listener
29+
lUDP []*socks.UDPListener
2830
udp bool
2931
}
3032

@@ -47,44 +49,52 @@ func (m *Mixed) Config() C.InboundConfig {
4749

4850
// Address implements constant.InboundListener
4951
func (m *Mixed) Address() string {
50-
return m.l.Address()
52+
var addrList []string
53+
for _, l := range m.l {
54+
addrList = append(addrList, l.Address())
55+
}
56+
return strings.Join(addrList, ",")
5157
}
5258

5359
// Listen implements constant.InboundListener
5460
func (m *Mixed) Listen(tunnel C.Tunnel) error {
55-
var err error
56-
m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuthStore(), m.Additions()...)
57-
if err != nil {
58-
return err
59-
}
60-
if m.udp {
61-
m.lUDP, err = socks.NewUDP(m.RawAddress(), tunnel, m.Additions()...)
61+
for _, addr := range strings.Split(m.RawAddress(), ",") {
62+
l, err := mixed.NewWithAuthenticator(addr, tunnel, m.config.Users.GetAuthStore(), m.Additions()...)
6263
if err != nil {
6364
return err
6465
}
66+
m.l = append(m.l, l)
67+
if m.udp {
68+
lUDP, err := socks.NewUDP(addr, tunnel, m.Additions()...)
69+
if err != nil {
70+
return err
71+
}
72+
m.lUDP = append(m.lUDP, lUDP)
73+
}
6574
}
6675
log.Infoln("Mixed(http+socks)[%s] proxy listening at: %s", m.Name(), m.Address())
6776
return nil
6877
}
6978

7079
// Close implements constant.InboundListener
7180
func (m *Mixed) Close() error {
72-
var err error
73-
if m.l != nil {
74-
if tcpErr := m.l.Close(); tcpErr != nil {
75-
err = tcpErr
81+
var errs []error
82+
for _, l := range m.l {
83+
err := l.Close()
84+
if err != nil {
85+
errs = append(errs, fmt.Errorf("close tcp listener %s err: %w", l.Address(), err))
7686
}
7787
}
78-
if m.udp && m.lUDP != nil {
79-
if udpErr := m.lUDP.Close(); udpErr != nil {
80-
if err == nil {
81-
err = udpErr
82-
} else {
83-
return fmt.Errorf("close tcp err: %s, close udp err: %s", err.Error(), udpErr.Error())
84-
}
88+
for _, l := range m.lUDP {
89+
err := l.Close()
90+
if err != nil {
91+
errs = append(errs, fmt.Errorf("close udp listener %s err: %w", l.Address(), err))
8592
}
8693
}
87-
return err
94+
if len(errs) > 0 {
95+
return errors.Join(errs...)
96+
}
97+
return nil
8898
}
8999

90100
var _ C.InboundListener = (*Mixed)(nil)

0 commit comments

Comments
 (0)