forked from nadoo/glider
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unix.go
129 lines (104 loc) · 2.59 KB
/
unix.go
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package unix
import (
"errors"
"net"
"net/url"
"os"
"strings"
"github.com/nadoo/glider/common/log"
"github.com/nadoo/glider/proxy"
)
// Unix domain socket struct
type Unix struct {
dialer proxy.Dialer
addr string
server proxy.Server
}
func init() {
proxy.RegisterServer("unix", NewUnixServer)
proxy.RegisterDialer("unix", NewUnixDialer)
}
// NewUnix returns unix fomain socket proxy
func NewUnix(s string, dialer proxy.Dialer) (*Unix, error) {
u, err := url.Parse(s)
if err != nil {
log.F("parse url err: %s", err)
return nil, err
}
p := &Unix{
dialer: dialer,
addr: u.Path,
}
return p, nil
}
// NewUnixDialer returns a unix domain socket dialer
func NewUnixDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
return NewUnix(s, dialer)
}
// NewUnixServer returns a unix domain socket server
func NewUnixServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
transport := strings.Split(s, ",")
// prepare transport listener
// TODO: check here
if len(transport) < 2 {
return nil, errors.New("[unix] malformd listener:" + s)
}
p, err := NewUnix(transport[0], dialer)
if err != nil {
return nil, err
}
p.server, err = proxy.ServerFromURL(transport[1], dialer)
if err != nil {
return nil, err
}
return p, nil
}
// ListenAndServe serves requests
func (s *Unix) ListenAndServe() {
os.Remove(s.addr)
l, err := net.Listen("unix", s.addr)
if err != nil {
log.F("[unix] failed to listen on %s: %v", s.addr, err)
return
}
defer l.Close()
log.F("[uinx] listening on %s", s.addr)
for {
c, err := l.Accept()
if err != nil {
log.F("[uinx] failed to accept: %v", err)
continue
}
go s.Serve(c)
}
}
// Serve serves requests
func (s *Unix) Serve(c net.Conn) {
// we know the internal server will close the connection after serve
// defer c.Close()
if s.server != nil {
s.server.Serve(c)
}
}
// Addr returns forwarder's address
func (s *Unix) Addr() string {
if s.addr == "" {
return s.dialer.Addr()
}
return s.addr
}
// NextDialer returns the next dialer
func (s *Unix) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) }
// Dial connects to the address addr on the network net via the proxy.
func (s *Unix) Dial(network, addr string) (net.Conn, error) {
// NOTE: must be the first dialer in a chain
rc, err := net.Dial("unix", s.addr)
if err != nil {
return nil, err
}
return rc, err
}
// DialUDP connects to the given address via the proxy
func (s *Unix) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
return nil, nil, errors.New("unix domain socket client does not support udp now")
}