Skip to content

Commit 0f4d6d0

Browse files
authored
Merge pull request #186 from openziti/add-group-secret
Add group secret for multi-underlay channels. Fixes #185
2 parents 3bc334d + b6f8958 commit 0f4d6d0

File tree

7 files changed

+43
-10
lines changed

7 files changed

+43
-10
lines changed

channel.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ type Channel interface {
4141

4242
type MultiChannel interface {
4343
Channel
44+
UnderlayAcceptor
4445
DialUnderlay(factory GroupedUnderlayFactory, underlayType string)
45-
AcceptUnderlay(underlay Underlay) bool
4646
GetUnderlayCountsByType() map[string]int
4747
GetUnderlayHandler() UnderlayHandler
4848
}
@@ -174,7 +174,7 @@ type DialUnderlayFactory interface {
174174
}
175175

176176
type GroupedUnderlayFactory interface {
177-
CreateGroupedUnderlay(groupId string, underlayType string, timeout time.Duration) (Underlay, error)
177+
CreateGroupedUnderlay(groupId string, groupedSecret []byte, underlayType string, timeout time.Duration) (Underlay, error)
178178
DialFailed(channel MultiChannel, underlayType string, attempt int)
179179
}
180180

classic_listener.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ func (self *classicListener) acceptConnection(peer transport.Conn) {
225225
}
226226
}
227227

228+
if isGrouped {
229+
if secret := hello.Headers[GroupSecretHeader]; len(secret) == 0 {
230+
newSecret := uuid.New()
231+
hello.Headers[GroupSecretHeader] = newSecret[:]
232+
}
233+
}
234+
228235
impl.init(hello.IdToken, connectionId, hello.Headers)
229236

230237
if err = self.ackHello(impl, request, true, ""); err == nil {
@@ -285,6 +292,9 @@ func (self *classicListener) ackHello(impl classicUnderlay, request *Message, su
285292
if underlayType, _ := request.GetStringHeader(TypeHeader); underlayType != "" {
286293
response.PutStringHeader(TypeHeader, underlayType)
287294
}
295+
if groupSecret := request.Headers[GroupSecretHeader]; len(groupSecret) > 0 {
296+
response.Headers[GroupSecretHeader] = groupSecret
297+
}
288298

289299
response.sequence = HelloSequence
290300

message.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const (
4848
TypeHeader = 7
4949
IdHeader = 8
5050
IsGroupedHeader = 9
51+
GroupSecretHeader = 10
5152

5253
// Headers in the range 128-255 inclusive will be reflected when creating replies
5354
ReflectedHeaderBitMask = 1 << 7

multi.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package channel
1818

1919
import (
20+
"bytes"
2021
"crypto/x509"
2122
"errors"
2223
"fmt"
@@ -83,6 +84,7 @@ type multiChannelImpl struct {
8384
underlayHandler UnderlayHandler
8485
userData interface{}
8586
replyCounter uint32
87+
groupSecret []byte
8688

8789
lock sync.Mutex
8890
underlays concurrenz.CopyOnWriteSlice[Underlay]
@@ -111,6 +113,12 @@ func NewMultiChannel(config *MultiChannelConfig) (MultiChannel, error) {
111113
impl.headers.Store(config.Underlay.Headers())
112114
impl.underlays.Append(config.Underlay)
113115

116+
if groupSecret := config.Underlay.Headers()[GroupSecretHeader]; len(groupSecret) == 0 {
117+
return nil, errors.New("no group secret header found for multi channel")
118+
} else {
119+
impl.groupSecret = groupSecret
120+
}
121+
114122
if err := bind(config.BindHandler, impl); err != nil {
115123
for _, u := range impl.underlays.Value() {
116124
if closeErr := u.Close(); closeErr != nil {
@@ -130,15 +138,23 @@ func NewMultiChannel(config *MultiChannelConfig) (MultiChannel, error) {
130138
return impl, nil
131139
}
132140

133-
func (self *multiChannelImpl) AcceptUnderlay(underlay Underlay) bool {
141+
func (self *multiChannelImpl) AcceptUnderlay(underlay Underlay) error {
134142
self.lock.Lock()
135143
defer self.lock.Unlock()
136144

145+
groupSecret := underlay.Headers()[GroupSecretHeader]
146+
if !bytes.Equal(groupSecret, self.groupSecret) {
147+
if err := underlay.Close(); err != nil {
148+
pfxlog.ContextLogger(self.Label()).WithError(err).Error("error closing underlay")
149+
}
150+
return fmt.Errorf("new underlay for '%s' not accepted: incorrect group secret", self.ConnectionId())
151+
}
152+
137153
if self.IsClosed() {
138154
if err := underlay.Close(); err != nil {
139155
pfxlog.ContextLogger(self.Label()).WithError(err).Error("error closing underlay")
140156
}
141-
return false
157+
return fmt.Errorf("new underlay for '%s' not accepted: multi-channel is closed", self.ConnectionId())
142158
}
143159

144160
self.certs.Store(underlay.Certificates())
@@ -149,7 +165,7 @@ func (self *multiChannelImpl) AcceptUnderlay(underlay Underlay) bool {
149165

150166
self.underlayHandler.HandleUnderlayAccepted(self, underlay)
151167

152-
return true
168+
return nil
153169
}
154170

155171
func (self *multiChannelImpl) startMultiplex(underlay Underlay) {
@@ -499,9 +515,12 @@ func (self *multiChannelImpl) DialUnderlay(factory GroupedUnderlayFactory, under
499515
dialTimeout = DefaultConnectTimeout
500516
}
501517

502-
underlay, err := factory.CreateGroupedUnderlay(self.ConnectionId(), underlayType, dialTimeout)
518+
underlay, err := factory.CreateGroupedUnderlay(self.ConnectionId(), self.groupSecret, underlayType, dialTimeout)
503519
if err == nil {
504-
self.AcceptUnderlay(underlay)
520+
if err = self.AcceptUnderlay(underlay); err != nil {
521+
log.WithError(err).Error("dial of new underlay failed")
522+
factory.DialFailed(self, underlayType, attempt)
523+
}
505524
return
506525
} else {
507526
factory.DialFailed(self, underlayType, attempt)

multi_listener.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ func (self *MultiListener) AcceptUnderlay(underlay Underlay) {
4141

4242
if ok {
4343
log.Info("found existing channel for underlay")
44-
mc.AcceptUnderlay(underlay)
44+
if err := mc.AcceptUnderlay(underlay); err != nil {
45+
log.WithError(err).Error("error accepting underlay")
46+
}
4547
} else {
4648
log.Info("no existing channel found for underlay")
4749
var err error

multi_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,11 @@ func (self *dialPriorityChannel) DialFailed(_ MultiChannel, _ string, attempt in
329329
time.Sleep(delay)
330330
}
331331

332-
func (self *dialPriorityChannel) CreateGroupedUnderlay(groupId string, underlayType string, timeout time.Duration) (Underlay, error) {
332+
func (self *dialPriorityChannel) CreateGroupedUnderlay(groupId string, groupSecret []byte, underlayType string, timeout time.Duration) (Underlay, error) {
333333
underlay, err := self.dialer.CreateWithHeaders(timeout, map[int32][]byte{
334334
TypeHeader: []byte(underlayType),
335335
ConnectionIdHeader: []byte(groupId),
336+
GroupSecretHeader: groupSecret,
336337
IsGroupedHeader: {1},
337338
})
338339
if err != nil {

version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.0
1+
4.1

0 commit comments

Comments
 (0)