@@ -4,14 +4,15 @@ import (
4
4
"crypto/tls"
5
5
"fmt"
6
6
"net"
7
+ "strconv"
7
8
"sync"
8
9
9
10
"github.com/grepplabs/kafka-proxy/config"
10
11
"github.com/grepplabs/kafka-proxy/pkg/libs/util"
11
12
"github.com/sirupsen/logrus"
12
13
)
13
14
14
- type ListenFunc func (cfg config. ListenerConfig ) (l net.Listener , err error )
15
+ type ListenFunc func (cfg * ListenerConfig ) (l net.Listener , err error )
15
16
16
17
type Listeners struct {
17
18
// Source of new connections to Kafka broker.
@@ -29,16 +30,11 @@ type Listeners struct {
29
30
disableDynamicListeners bool
30
31
dynamicSequentialMinPort int
31
32
32
- brokerToListenerConfig map [string ]config.ListenerConfig
33
- brokerIdToIdListenerConfig map [int32 ]config.IdListenerConfig
34
- lock sync.RWMutex
33
+ brokerToListenerConfig map [string ]* ListenerConfig
34
+ lock sync.RWMutex
35
35
}
36
36
37
37
func NewListeners (cfg * config.Config ) (* Listeners , error ) {
38
-
39
- defaultListenerIP := cfg .Proxy .DefaultListenerIP
40
- dynamicAdvertisedListener := cfg .Proxy .DynamicAdvertisedListener
41
-
42
38
tcpConnOptions := TCPConnOptions {
43
39
KeepAlive : cfg .Proxy .ListenerKeepAlive ,
44
40
ReadBufferSize : cfg .Proxy .ListenerReadBufferSize ,
@@ -54,7 +50,7 @@ func NewListeners(cfg *config.Config) (*Listeners, error) {
54
50
}
55
51
}
56
52
57
- listenFunc := func (cfg config. ListenerConfig ) (net.Listener , error ) {
53
+ listenFunc := func (cfg * ListenerConfig ) (net.Listener , error ) {
58
54
if tlsConfig != nil {
59
55
return tls .Listen ("tcp" , cfg .ListenerAddress , tlsConfig )
60
56
}
@@ -66,34 +62,31 @@ func NewListeners(cfg *config.Config) (*Listeners, error) {
66
62
return nil , err
67
63
}
68
64
69
- brokerIdToIdListenerConfig := make (map [int32 ]config.IdListenerConfig )
70
-
71
65
return & Listeners {
72
- defaultListenerIP : defaultListenerIP ,
73
- dynamicAdvertisedListener : dynamicAdvertisedListener ,
74
- connSrc : make (chan Conn , 1 ),
75
- brokerToListenerConfig : brokerToListenerConfig ,
76
- brokerIdToIdListenerConfig : brokerIdToIdListenerConfig ,
77
- tcpConnOptions : tcpConnOptions ,
78
- listenFunc : listenFunc ,
79
- deterministicListeners : cfg .Proxy .DeterministicListeners ,
80
- disableDynamicListeners : cfg .Proxy .DisableDynamicListeners ,
81
- dynamicSequentialMinPort : cfg .Proxy .DynamicSequentialMinPort ,
66
+ defaultListenerIP : cfg .Proxy .DefaultListenerIP ,
67
+ dynamicAdvertisedListener : cfg .Proxy .DynamicAdvertisedListener ,
68
+ connSrc : make (chan Conn , 1 ),
69
+ brokerToListenerConfig : brokerToListenerConfig ,
70
+ tcpConnOptions : tcpConnOptions ,
71
+ listenFunc : listenFunc ,
72
+ deterministicListeners : cfg .Proxy .DeterministicListeners ,
73
+ disableDynamicListeners : cfg .Proxy .DisableDynamicListeners ,
74
+ dynamicSequentialMinPort : cfg .Proxy .DynamicSequentialMinPort ,
82
75
}, nil
83
76
}
84
77
85
- func getBrokerToListenerConfig (cfg * config.Config ) (map [string ]config. ListenerConfig , error ) {
86
- brokerToListenerConfig := make (map [string ]config. ListenerConfig )
78
+ func getBrokerToListenerConfig (cfg * config.Config ) (map [string ]* ListenerConfig , error ) {
79
+ brokerToListenerConfig := make (map [string ]* ListenerConfig )
87
80
88
81
for _ , v := range cfg .Proxy .BootstrapServers {
89
82
if lc , ok := brokerToListenerConfig [v .BrokerAddress ]; ok {
90
83
if lc .ListenerAddress != v .ListenerAddress || lc .AdvertisedAddress != v .AdvertisedAddress {
91
- return nil , fmt .Errorf ("bootstrap server mapping %s configured twice: %v and %v" , v .BrokerAddress , v , lc )
84
+ return nil , fmt .Errorf ("bootstrap server mapping %s configured twice: %v and %v" , v .BrokerAddress , v , lc . ToListenerConfig () )
92
85
}
93
86
continue
94
87
}
95
88
logrus .Infof ("Bootstrap server %s advertised as %s" , v .BrokerAddress , v .AdvertisedAddress )
96
- brokerToListenerConfig [v .BrokerAddress ] = v
89
+ brokerToListenerConfig [v .BrokerAddress ] = FromListenerConfig ( v )
97
90
}
98
91
99
92
externalToListenerConfig := make (map [string ]config.ListenerConfig )
@@ -118,7 +111,7 @@ func getBrokerToListenerConfig(cfg *config.Config) (map[string]config.ListenerCo
118
111
continue
119
112
}
120
113
logrus .Infof ("External server %s advertised as %s" , v .BrokerAddress , v .AdvertisedAddress )
121
- brokerToListenerConfig [v .BrokerAddress ] = v
114
+ brokerToListenerConfig [v .BrokerAddress ] = FromListenerConfig ( v )
122
115
}
123
116
return brokerToListenerConfig , nil
124
117
}
@@ -132,32 +125,28 @@ func (p *Listeners) GetNetAddressMapping(brokerHost string, brokerPort int32, br
132
125
133
126
p .lock .RLock ()
134
127
listenerConfig , ok := p .brokerToListenerConfig [brokerAddress ]
135
- idListenerConfig , brokerIdFound := p .brokerIdToIdListenerConfig [brokerId ]
136
128
p .lock .RUnlock ()
137
129
138
130
if ok {
139
- logrus .Debugf ("Address mappings broker=%s, listener=%s, advertised=%s" , listenerConfig .BrokerAddress , listenerConfig .ListenerAddress , listenerConfig .AdvertisedAddress )
131
+ logrus .Debugf ("Address mappings broker=%s, listener=%s, advertised=%s, brokerId=%d " , listenerConfig .GetBrokerAddress () , listenerConfig .ListenerAddress , listenerConfig .AdvertisedAddress , brokerId )
140
132
return util .SplitHostPort (listenerConfig .AdvertisedAddress )
141
133
}
142
134
if ! p .disableDynamicListeners {
143
- if brokerIdFound {
144
- logrus .Infof ("Broker ID %d has a new advertised listener, closing existing dynamic listener" , brokerId )
145
- // Existing broker ID found, but with a different upstream broker
146
- // Close existing listener, remove two mappings:
147
- // * ID to removed upstream broker
148
- // * removed upstream broker
149
- idListenerConfig .Listener .Close ()
150
- p .lock .Lock ()
151
- delete (p .brokerIdToIdListenerConfig , brokerId )
152
- delete (p .brokerToListenerConfig , idListenerConfig .BrokerAddress )
153
- p .lock .Unlock ()
154
- }
155
135
logrus .Infof ("Starting dynamic listener for broker %s" , brokerAddress )
156
136
return p .ListenDynamicInstance (brokerAddress , brokerId )
157
137
}
158
138
return "" , 0 , fmt .Errorf ("net address mapping for %s:%d was not found" , brokerHost , brokerPort )
159
139
}
160
140
141
+ func (p * Listeners ) findListenerConfig (brokerId int32 ) * ListenerConfig {
142
+ for _ , listenerConfig := range p .brokerToListenerConfig {
143
+ if listenerConfig .BrokerID == brokerId {
144
+ return listenerConfig
145
+ }
146
+ }
147
+ return nil
148
+ }
149
+
161
150
func (p * Listeners ) ListenDynamicInstance (brokerAddress string , brokerId int32 ) (string , int32 , error ) {
162
151
p .lock .Lock ()
163
152
defer p .lock .Unlock ()
@@ -166,18 +155,34 @@ func (p *Listeners) ListenDynamicInstance(brokerAddress string, brokerId int32)
166
155
return util .SplitHostPort (v .AdvertisedAddress )
167
156
}
168
157
169
- var defaultListenerAddress string
170
-
158
+ var listenerAddress string
171
159
if p .deterministicListeners {
172
- defaultListenerAddress = net .JoinHostPort (p .defaultListenerIP , fmt .Sprint (p .dynamicSequentialMinPort + int (brokerId )))
160
+ if brokerId < 0 {
161
+ return "" , 0 , fmt .Errorf ("brokerId is negative %s %d" , brokerAddress , brokerId )
162
+ }
163
+ deterministicPort := p .dynamicSequentialMinPort + int (brokerId )
164
+ if deterministicPort < p .dynamicSequentialMinPort {
165
+ return "" , 0 , fmt .Errorf ("port assignment overflow %s %d: %d" , brokerAddress , brokerId , deterministicPort )
166
+ }
167
+ listenerAddress = net .JoinHostPort (p .defaultListenerIP , strconv .Itoa (deterministicPort ))
168
+ cfg := p .findListenerConfig (brokerId )
169
+ if cfg != nil {
170
+ oldBrokerAddress := cfg .GetBrokerAddress ()
171
+ if oldBrokerAddress != brokerAddress {
172
+ delete (p .brokerToListenerConfig , oldBrokerAddress )
173
+ cfg .SetBrokerAddress (brokerAddress )
174
+ p .brokerToListenerConfig [brokerAddress ] = cfg
175
+ logrus .Infof ("Broker address changed listener %s for new address %s old address %s brokerId %d advertised as %s" , cfg .ListenerAddress , cfg .GetBrokerAddress (), oldBrokerAddress , cfg .BrokerID , cfg .AdvertisedAddress )
176
+ }
177
+ return util .SplitHostPort (cfg .AdvertisedAddress )
178
+ }
173
179
} else {
174
- defaultListenerAddress = net .JoinHostPort (p .defaultListenerIP , fmt . Sprint (p .dynamicSequentialMinPort ))
180
+ listenerAddress = net .JoinHostPort (p .defaultListenerIP , strconv . Itoa (p .dynamicSequentialMinPort ))
175
181
if p .dynamicSequentialMinPort != 0 {
176
182
p .dynamicSequentialMinPort += 1
177
183
}
178
184
}
179
-
180
- cfg := config.ListenerConfig {ListenerAddress : defaultListenerAddress , BrokerAddress : brokerAddress }
185
+ cfg := NewListenerConfig (brokerAddress , listenerAddress , "" , brokerId )
181
186
l , err := listenInstance (p .connSrc , cfg , p .tcpConnOptions , p .listenFunc )
182
187
if err != nil {
183
188
return "" , 0 , err
@@ -189,12 +194,11 @@ func (p *Listeners) ListenDynamicInstance(brokerAddress string, brokerId int32)
189
194
if dynamicAdvertisedListener == "" {
190
195
dynamicAdvertisedListener = p .defaultListenerIP
191
196
}
197
+ cfg .AdvertisedAddress = net .JoinHostPort (dynamicAdvertisedListener , fmt .Sprint (port ))
198
+ cfg .ListenerAddress = address
192
199
193
- advertisedAddress := net .JoinHostPort (dynamicAdvertisedListener , fmt .Sprint (port ))
194
- p .brokerToListenerConfig [brokerAddress ] = config.ListenerConfig {BrokerAddress : brokerAddress , ListenerAddress : address , AdvertisedAddress : advertisedAddress }
195
- p .brokerIdToIdListenerConfig [brokerId ] = config.IdListenerConfig {BrokerAddress : brokerAddress , Listener : l }
196
-
197
- logrus .Infof ("Dynamic listener %s for broker %s advertised as %s" , address , brokerAddress , advertisedAddress )
200
+ p .brokerToListenerConfig [brokerAddress ] = cfg
201
+ logrus .Infof ("Dynamic listener %s for broker %s brokerId %d advertised as %s" , cfg .ListenerAddress , cfg .GetBrokerAddress (), cfg .BrokerID , cfg .AdvertisedAddress )
198
202
199
203
return dynamicAdvertisedListener , int32 (port ), nil
200
204
}
@@ -205,15 +209,16 @@ func (p *Listeners) ListenInstances(cfgs []config.ListenerConfig) (<-chan Conn,
205
209
206
210
// allows multiple local addresses to point to the remote
207
211
for _ , v := range cfgs {
208
- _ , err := listenInstance (p .connSrc , v , p .tcpConnOptions , p .listenFunc )
212
+ cfg := FromListenerConfig (v )
213
+ _ , err := listenInstance (p .connSrc , cfg , p .tcpConnOptions , p .listenFunc )
209
214
if err != nil {
210
215
return nil , err
211
216
}
212
217
}
213
218
return p .connSrc , nil
214
219
}
215
220
216
- func listenInstance (dst chan <- Conn , cfg config. ListenerConfig , opts TCPConnOptions , listenFunc ListenFunc ) (net.Listener , error ) {
221
+ func listenInstance (dst chan <- Conn , cfg * ListenerConfig , opts TCPConnOptions , listenFunc ListenFunc ) (net.Listener , error ) {
217
222
l , err := listenFunc (cfg )
218
223
if err != nil {
219
224
return nil , err
@@ -222,20 +227,28 @@ func listenInstance(dst chan<- Conn, cfg config.ListenerConfig, opts TCPConnOpti
222
227
for {
223
228
c , err := l .Accept ()
224
229
if err != nil {
225
- logrus .Infof ("Error in accept for %q on %v: %v" , cfg , cfg .ListenerAddress , err )
230
+ logrus .Infof ("Error in accept for %q on %v: %v" , cfg . ToListenerConfig () , cfg .ListenerAddress , err )
226
231
l .Close ()
227
232
return
228
233
}
229
234
if tcpConn , ok := c .(* net.TCPConn ); ok {
230
235
if err := opts .setTCPConnOptions (tcpConn ); err != nil {
231
- logrus .Infof ("WARNING: Error while setting TCP options for accepted connection %q on %v: %v" , cfg , l .Addr ().String (), err )
236
+ logrus .Infof ("WARNING: Error while setting TCP options for accepted connection %q on %v: %v" , cfg . ToListenerConfig () , l .Addr ().String (), err )
232
237
}
233
238
}
234
- logrus .Infof ("New connection for %s" , cfg .BrokerAddress )
235
- dst <- Conn {BrokerAddress : cfg .BrokerAddress , LocalConnection : c }
239
+ brokerAddress := cfg .GetBrokerAddress ()
240
+ if cfg .BrokerID != UnknownBrokerID {
241
+ logrus .Infof ("New connection for %s brokerId %d" , brokerAddress , cfg .BrokerID )
242
+ } else {
243
+ logrus .Infof ("New connection for %s" , brokerAddress )
244
+ }
245
+ dst <- Conn {BrokerAddress : brokerAddress , LocalConnection : c }
236
246
}
237
247
})
238
-
239
- logrus .Infof ("Listening on %s (%s) for remote %s" , cfg .ListenerAddress , l .Addr ().String (), cfg .BrokerAddress )
248
+ if cfg .BrokerID != UnknownBrokerID {
249
+ logrus .Infof ("Listening on %s (%s) for remote %s broker %d" , cfg .ListenerAddress , l .Addr ().String (), cfg .GetBrokerAddress (), cfg .BrokerID )
250
+ } else {
251
+ logrus .Infof ("Listening on %s (%s) for remote %s" , cfg .ListenerAddress , l .Addr ().String (), cfg .GetBrokerAddress ())
252
+ }
240
253
return l , nil
241
254
}
0 commit comments