@@ -2,6 +2,9 @@ package sub
2
2
3
3
import (
4
4
"fmt"
5
+ "net"
6
+ "sort"
7
+ "strings"
5
8
6
9
relay_cfg "github.com/Ehco1996/ehco/internal/relay/conf"
7
10
"gopkg.in/yaml.v3"
@@ -36,6 +39,24 @@ func (c *ClashSub) ToClashConfigYaml() ([]byte, error) {
36
39
return yaml .Marshal (c .cCfg )
37
40
}
38
41
42
+ func (c * ClashSub ) ToGroupedClashConfigYaml () ([]byte , error ) {
43
+ groupProxy := c .cCfg .groupByLongestCommonPrefix ()
44
+ ps := []* Proxies {}
45
+ groupNameList := []string {}
46
+ for groupName := range groupProxy {
47
+ groupNameList = append (groupNameList , groupName )
48
+ }
49
+ sort .Strings (groupNameList )
50
+ for _ , groupName := range groupNameList {
51
+ proxies := groupProxy [groupName ]
52
+ // only use first proxy will be show in proxy provider, other will be merged into load balance in relay
53
+ p := proxies [0 ].getOrCreateGroupLeader ()
54
+ ps = append (ps , p )
55
+ }
56
+ groupedCfg := & clashConfig {& ps }
57
+ return yaml .Marshal (groupedCfg )
58
+ }
59
+
39
60
func (c * ClashSub ) Refresh () error {
40
61
// get new clash sub by url
41
62
newSub , err := NewClashSubByURL (c .URL , c .Name )
@@ -82,13 +103,51 @@ func (c *ClashSub) Refresh() error {
82
103
83
104
func (c * ClashSub ) ToRelayConfigs (listenHost string ) ([]* relay_cfg.Config , error ) {
84
105
relayConfigs := []* relay_cfg.Config {}
106
+ // generate relay config for each proxy
85
107
for _ , proxy := range * c .cCfg .Proxies {
86
- newName := fmt .Sprintf ("%s-%s" , c .Name , proxy .Name )
108
+ var newName string
109
+ if strings .HasSuffix (proxy .Name , "-" ) {
110
+ newName = fmt .Sprintf ("%s%s" , proxy .Name , c .Name )
111
+ } else {
112
+ newName = fmt .Sprintf ("%s-%s" , proxy .Name , c .Name )
113
+ }
114
+
87
115
rc , err := proxy .ToRelayConfig (listenHost , newName )
88
116
if err != nil {
89
117
return nil , err
90
118
}
91
119
relayConfigs = append (relayConfigs , rc )
92
120
}
121
+
122
+ // generate relay config for each group
123
+ groupProxy := c .cCfg .groupByLongestCommonPrefix ()
124
+ for groupName , proxies := range groupProxy {
125
+ // only use first proxy will be show in proxy provider, other will be merged into load balance in relay
126
+ groupLeader := proxies [0 ].getOrCreateGroupLeader ()
127
+ var newName string
128
+ if strings .HasSuffix (groupName , "-" ) {
129
+ newName = fmt .Sprintf ("%slb" , groupName )
130
+ } else {
131
+ newName = fmt .Sprintf ("%s-lb" , groupName )
132
+ }
133
+ rc , err := groupLeader .ToRelayConfig (listenHost , newName )
134
+ if err != nil {
135
+ return nil , err
136
+ }
137
+
138
+ // add other proxies in group to relay config
139
+ for _ , proxy := range proxies [1 :] {
140
+ remote := net .JoinHostPort (proxy .rawServer , proxy .rawPort )
141
+ // skip duplicate remote, because the relay cfg for this leader will be cached when first init
142
+ if strInArray (remote , rc .TCPRemotes ) {
143
+ continue
144
+ }
145
+ rc .TCPRemotes = append (rc .TCPRemotes , remote )
146
+ if proxy .UDP {
147
+ rc .UDPRemotes = append (rc .UDPRemotes , remote )
148
+ }
149
+ }
150
+ relayConfigs = append (relayConfigs , rc )
151
+ }
93
152
return relayConfigs , nil
94
153
}
0 commit comments