Skip to content

Commit 45e7db1

Browse files
author
Matt Hamann
committed
Add support for DNS SRV lookups
1 parent d6fe180 commit 45e7db1

File tree

8 files changed

+130
-3
lines changed

8 files changed

+130
-3
lines changed

glide.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ import:
55
- package: golang.org/x/net
66
subpackages:
77
- websocket
8+
- package: github.com/benschw/srv-lb
9+
subpackages:
10+
- dns
11+
- lb

resolver/dns.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package resolver
2+
3+
import (
4+
"strings"
5+
6+
"github.com/benschw/srv-lb/lb"
7+
)
8+
9+
// DNSConfig accepts an address and optional load balancer config
10+
type DNSConfig struct {
11+
Addr string
12+
LbCfg *lb.Config
13+
}
14+
15+
// ResolveSrvAddr returns a load-balanced host:port based on DNS SRV lookup (or `addr` if not a hostname)
16+
func ResolveSrvAddr(dnsCfg DNSConfig) (string, error) {
17+
addr := dnsCfg.Addr
18+
19+
if v := strings.Split(addr, ":"); len(v) < 2 {
20+
var cfg *lb.Config
21+
var err error
22+
if dnsCfg.LbCfg == nil {
23+
cfg, err = lb.DefaultConfig()
24+
25+
if err != nil {
26+
return addr, err
27+
}
28+
} else {
29+
cfg = dnsCfg.LbCfg
30+
}
31+
32+
l := lb.New(cfg, addr)
33+
resolvAddr, err := l.Next()
34+
35+
if err == nil {
36+
addr = resolvAddr.String()
37+
}
38+
}
39+
40+
return addr, nil
41+
}

resolver/dns_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package resolver
2+
3+
import (
4+
"testing"
5+
6+
"github.com/benschw/srv-lb/lb"
7+
)
8+
9+
func TestSrvLookup(t *testing.T) {
10+
lbCfg, _ := lb.DefaultConfig()
11+
lbCfg.Strategy = MockStrategy
12+
dnsCfg := DNSConfig{Addr: "foo.example.com", LbCfg: lbCfg}
13+
14+
addr, _ := ResolveSrvAddr(dnsCfg)
15+
16+
if addr != "1.2.3.4:1234" {
17+
t.Error("expected address string of 1.2.3.4:1234, got:", addr)
18+
}
19+
}
20+
21+
func TestIpPassthrough(t *testing.T) {
22+
dnsCfg := DNSConfig{Addr: "10.0.0.1:1234"}
23+
24+
addr, _ := ResolveSrvAddr(dnsCfg)
25+
26+
if addr != "10.0.0.1:1234" {
27+
t.Error("expected output to equal input (10.0.0.1:1234), got:", addr)
28+
}
29+
}

resolver/lb_mock_strategy.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package resolver
2+
3+
import (
4+
"github.com/benschw/srv-lb/dns"
5+
"github.com/benschw/srv-lb/lb"
6+
)
7+
8+
// MockStrategy is used for testing DNS load balancing
9+
const MockStrategy lb.StrategyType = "mock"
10+
11+
// New creates a new instance of the load balancer
12+
func New(lib dns.Lookup) lb.GenericLoadBalancer {
13+
lb := new(MockClb)
14+
lb.dnsLib = lib
15+
return lb
16+
}
17+
18+
// MockClb contains the dnslib
19+
type MockClb struct {
20+
dnsLib dns.Lookup
21+
}
22+
23+
// Next gets the next server in the available nodes
24+
func (lb *MockClb) Next(name string) (dns.Address, error) {
25+
return dns.Address{Address: "1.2.3.4", Port: 1234}, nil
26+
}
27+
28+
func init() {
29+
lb.RegisterStrategy(MockStrategy, New)
30+
}

transports/tcp/tcp.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"net"
55

66
"github.com/gliderlabs/logspout/adapters/raw"
7+
"github.com/gliderlabs/logspout/resolver"
78
"github.com/gliderlabs/logspout/router"
89
)
910

@@ -21,7 +22,12 @@ func rawTCPAdapter(route *router.Route) (router.LogAdapter, error) {
2122
type tcpTransport int
2223

2324
func (t *tcpTransport) Dial(addr string, options map[string]string) (net.Conn, error) {
24-
raddr, err := net.ResolveTCPAddr("tcp", addr)
25+
daddr, err := resolver.ResolveSrvAddr(resolver.DNSConfig{Addr: addr})
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
raddr, err := net.ResolveTCPAddr("tcp", daddr)
2531
if err != nil {
2632
return nil, err
2733
}

transports/tls/tls.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net"
66

77
"github.com/gliderlabs/logspout/adapters/raw"
8+
"github.com/gliderlabs/logspout/resolver"
89
"github.com/gliderlabs/logspout/router"
910
)
1011

@@ -22,7 +23,12 @@ func rawTLSAdapter(route *router.Route) (router.LogAdapter, error) {
2223
type tlsTransport int
2324

2425
func (t *tlsTransport) Dial(addr string, options map[string]string) (net.Conn, error) {
25-
conn, err := tls.Dial("tcp", addr, nil)
26+
daddr, err := resolver.ResolveSrvAddr(resolver.DNSConfig{Addr: addr})
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
conn, err := tls.Dial("tcp", daddr, nil)
2632
if err != nil {
2733
return nil, err
2834
}

transports/udp/udp.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"net"
55

66
"github.com/gliderlabs/logspout/adapters/raw"
7+
"github.com/gliderlabs/logspout/resolver"
78
"github.com/gliderlabs/logspout/router"
89
)
910

@@ -26,7 +27,12 @@ func rawUDPAdapter(route *router.Route) (router.LogAdapter, error) {
2627
type udpTransport int
2728

2829
func (t *udpTransport) Dial(addr string, options map[string]string) (net.Conn, error) {
29-
raddr, err := net.ResolveUDPAddr("udp", addr)
30+
daddr, err := resolver.ResolveSrvAddr(resolver.DNSConfig{Addr: addr})
31+
if err != nil {
32+
return nil, err
33+
}
34+
35+
raddr, err := net.ResolveUDPAddr("udp", daddr)
3036
if err != nil {
3137
return nil, err
3238
}

0 commit comments

Comments
 (0)