-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservice_client.go
More file actions
85 lines (75 loc) · 2.02 KB
/
service_client.go
File metadata and controls
85 lines (75 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package fcbreak
import (
"context"
"fmt"
"log"
"net"
"strings"
"sync"
reuse "github.com/libp2p/go-reuseport"
proxyproto "github.com/pires/go-proxyproto"
)
func NewService(name string, cfg *ServiceConf) Service {
var s Service
switch strings.ToLower(cfg.Scheme) {
case "tcp":
s = NewTCPService(name, cfg)
case "http":
fallthrough
case "https":
s = NewHTTPService(name, cfg)
default:
log.Printf("scheme %s is not supported", cfg.Scheme)
}
return s
}
type Service interface {
Serve(net.Listener) error
Shutdown(context.Context) error
GetCfg() *ServiceConf
GetInfo() *ServiceInfo
SetExposedAddr(addr string)
}
// listenForService listen for common connections
func listenForService(s Service) (net.Listener, error) {
dl, err := reuse.Listen("tcp", fmt.Sprintf("%s:%d", s.GetCfg().BindAddr, s.GetCfg().BindPort))
if err != nil {
log.Fatal("Listen: ", err)
return nil, err
}
log.Printf("Service [%s] Listen: %s://%s", s.GetInfo().Name, s.GetInfo().Scheme, dl.Addr().String())
return &svcInitListener{Listener: dl, isReflected: false}, nil
}
// listenProxyForService is listen for proxy protocol connections from relector
func listenProxyForService(s Service) (net.Listener, error) {
l, err := reuse.Listen("tcp", fmt.Sprintf("%s:0", s.GetCfg().BindAddr))
if err != nil {
log.Fatal("Listen: ", err)
return nil, err
}
log.Printf("Service [%s] Listen: %s+proxyproto://%s", s.GetInfo().Name, s.GetInfo().Scheme, l.Addr().String())
return &svcInitListener{Listener: &proxyproto.Listener{Listener: l}, isReflected: true}, nil
}
type svcInitListener struct {
net.Listener
isReflected bool
once sync.Once
}
type svcInitConn struct {
net.Conn
IsReflected bool // Indicates if the connection is via server
}
func (l *svcInitListener) Accept() (net.Conn, error) {
c, err := l.Listener.Accept()
if err != nil {
return nil, err
}
return svcInitConn{c, l.isReflected}, nil
}
// withStand multiple Closes
func (l *svcInitListener) Close() (err error) {
l.once.Do(func() {
err = l.Listener.Close()
})
return
}