Skip to content

Commit d6b0468

Browse files
authored
Merge pull request #1481 from dcherednik/explicit_ip_support_rc1
Support for external ip discovery
2 parents 14ec2f2 + 4b40c7b commit d6b0468

File tree

5 files changed

+96
-15
lines changed

5 files changed

+96
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Added ip discovery. Server can show own ip address and target hostname in the ListEndpoint message. These fields are used to bypass DNS resolving.
2+
13
## v3.81.0
24
* Added error ErrMessagesPutToInternalQueueBeforeError to topic writer
35
* Added write to topics within transactions

internal/conn/conn.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ func (c *conn) GetState() (s State) {
177177
return State(c.state.Load())
178178
}
179179

180+
func makeDialOption(overrideHost string) []grpc.DialOption {
181+
dialOption := []grpc.DialOption{
182+
grpc.WithStatsHandler(statsHandler{}),
183+
}
184+
185+
if len(overrideHost) != 0 {
186+
dialOption = append(dialOption, grpc.WithAuthority(overrideHost))
187+
}
188+
189+
return dialOption
190+
}
191+
180192
func (c *conn) realConn(ctx context.Context) (cc *grpc.ClientConn, err error) {
181193
if c.isClosed() {
182194
return nil, xerrors.WithStackTrace(errClosedConnection)
@@ -208,10 +220,11 @@ func (c *conn) realConn(ctx context.Context) (cc *grpc.ClientConn, err error) {
208220
// three slashes in "ydb:///" is ok. It needs for good parse scheme in grpc resolver.
209221
address := "ydb:///" + c.endpoint.Address()
210222

223+
dialOption := makeDialOption(c.endpoint.OverrideHost())
224+
211225
cc, err = grpc.DialContext(ctx, address, append( //nolint:staticcheck,nolintlint
212-
[]grpc.DialOption{
213-
grpc.WithStatsHandler(statsHandler{}),
214-
}, c.config.GrpcDialOptions()...,
226+
dialOption,
227+
c.config.GrpcDialOptions()...,
215228
)...)
216229
if err != nil {
217230
if xerrors.IsContextError(err) {

internal/discovery/discovery.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ func discover(
8181
endpoint.WithLocalDC(e.GetLocation() == location),
8282
endpoint.WithServices(e.GetService()),
8383
endpoint.WithLastUpdated(config.Clock().Now()),
84+
endpoint.WithIPV4(e.GetIpV4()),
85+
endpoint.WithIPV6(e.GetIpV6()),
86+
endpoint.WithSslTargetNameOverride(e.GetSslTargetNameOverride()),
8487
))
8588
}
8689
}

internal/endpoint/endpoint.go

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type (
1616
Location() string
1717
LastUpdated() time.Time
1818
LoadFactor() float32
19+
OverrideHost() string
1920

2021
// Deprecated: LocalDC check "local" by compare endpoint location with discovery "selflocation" field.
2122
// It work good only if connection url always point to local dc.
@@ -33,11 +34,14 @@ type (
3334
)
3435

3536
type endpoint struct { //nolint:maligned
36-
mu sync.RWMutex
37-
id uint32
38-
address string
39-
location string
40-
services []string
37+
mu sync.RWMutex
38+
id uint32
39+
address string
40+
location string
41+
services []string
42+
ipv4 []string
43+
ipv6 []string
44+
sslNameOverride string
4145

4246
loadFactor float32
4347
lastUpdated time.Time
@@ -50,13 +54,16 @@ func (e *endpoint) Copy() Endpoint {
5054
defer e.mu.RUnlock()
5155

5256
return &endpoint{
53-
id: e.id,
54-
address: e.address,
55-
location: e.location,
56-
services: append(make([]string, 0, len(e.services)), e.services...),
57-
loadFactor: e.loadFactor,
58-
local: e.local,
59-
lastUpdated: e.lastUpdated,
57+
id: e.id,
58+
address: e.address,
59+
location: e.location,
60+
services: append(make([]string, 0, len(e.services)), e.services...),
61+
ipv4: append(make([]string, 0, len(e.ipv4)), e.ipv4...),
62+
ipv6: append(make([]string, 0, len(e.ipv6)), e.ipv6...),
63+
sslNameOverride: e.sslNameOverride,
64+
loadFactor: e.loadFactor,
65+
local: e.local,
66+
lastUpdated: e.lastUpdated,
6067
}
6168
}
6269

@@ -81,13 +88,47 @@ func (e *endpoint) NodeID() uint32 {
8188
return e.id
8289
}
8390

91+
func getResolvedAddr(e *endpoint, useV6 bool) string {
92+
var ip string
93+
if useV6 {
94+
ip = "[" + e.ipv6[0] + "]"
95+
} else {
96+
ip = e.ipv4[0]
97+
}
98+
99+
end := len(e.address)
100+
101+
for i := end - 1; i >= 0; i-- {
102+
if e.address[i] == ':' {
103+
return ip + e.address[i:]
104+
}
105+
}
106+
107+
return e.address
108+
}
109+
84110
func (e *endpoint) Address() (address string) {
85111
e.mu.RLock()
86112
defer e.mu.RUnlock()
87113

114+
if len(e.ipv4) != 0 {
115+
return getResolvedAddr(e, false)
116+
}
117+
118+
if len(e.ipv6) != 0 {
119+
return getResolvedAddr(e, true)
120+
}
121+
88122
return e.address
89123
}
90124

125+
func (e *endpoint) OverrideHost() string {
126+
e.mu.RLock()
127+
defer e.mu.RUnlock()
128+
129+
return e.sslNameOverride
130+
}
131+
91132
func (e *endpoint) Location() string {
92133
e.mu.RLock()
93134
defer e.mu.RUnlock()
@@ -168,6 +209,24 @@ func WithLastUpdated(ts time.Time) Option {
168209
}
169210
}
170211

212+
func WithIPV4(ipv4 []string) Option {
213+
return func(e *endpoint) {
214+
e.ipv4 = append(e.ipv4, ipv4...)
215+
}
216+
}
217+
218+
func WithIPV6(ipv6 []string) Option {
219+
return func(e *endpoint) {
220+
e.ipv6 = append(e.ipv6, ipv6...)
221+
}
222+
}
223+
224+
func WithSslTargetNameOverride(nameOverride string) Option {
225+
return func(e *endpoint) {
226+
e.sslNameOverride = nameOverride
227+
}
228+
}
229+
171230
func New(address string, opts ...Option) *endpoint {
172231
e := &endpoint{
173232
address: address,

internal/mock/conn.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ func (e *Endpoint) LoadFactor() float32 {
115115
panic("not implemented in mock")
116116
}
117117

118+
func (e *Endpoint) OverrideHost() string {
119+
panic("not implemented in mock")
120+
}
121+
118122
func (e *Endpoint) String() string {
119123
panic("not implemented in mock")
120124
}

0 commit comments

Comments
 (0)