1717package channel
1818
1919import (
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
155171func (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 )
0 commit comments