Skip to content

Commit f957ca2

Browse files
committed
proxy: add watchdog
1 parent 7e1340c commit f957ca2

3 files changed

Lines changed: 164 additions & 25 deletions

File tree

proxy/main.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ func main() {
105105
settings,
106106
)
107107

108+
newWatchdog(ctx, 5*time.Second)
109+
108110
select {
109111
case <-ctx.Done():
110112
}
@@ -143,6 +145,23 @@ func newSocks5Server(
143145
func (self *socks5Server) run() {
144146
defer self.cancel()
145147

148+
validUser := func(username string, password string, userAddr string) bool {
149+
proxyId, err := model.ParseSignedProxyId(username)
150+
if err != nil {
151+
return false
152+
}
153+
154+
addrPort, err := netip.ParseAddrPort(userAddr)
155+
if err != nil {
156+
glog.V(1).Infof("[socks]user address %s err=%s\n", userAddr, err)
157+
return false
158+
}
159+
160+
glog.V(1).Infof("[socks]user valid %s (%s)\n", proxyId, addrPort)
161+
162+
return self.proxyDeviceManager.ValidCaller(proxyId, addrPort.Addr())
163+
}
164+
146165
connectDial := func(ctx context.Context, r proxy.SocksRequest, network string, addr string) (net.Conn, error) {
147166
username := r.AuthContext.Payload["username"]
148167
// the proxy id was already verified by the credential store
@@ -161,23 +180,6 @@ func (self *socks5Server) run() {
161180
return pd.Tun().DialContext(ctx, network, addr)
162181
}
163182

164-
validUser := func(username string, password string, userAddr string) bool {
165-
proxyId, err := model.ParseSignedProxyId(username)
166-
if err != nil {
167-
return false
168-
}
169-
170-
addrPort, err := netip.ParseAddrPort(userAddr)
171-
if err != nil {
172-
glog.V(1).Infof("[socks]user address %s err=%s\n", userAddr, err)
173-
return false
174-
}
175-
176-
glog.V(1).Infof("[socks]user valid %s (%s)\n", proxyId, addrPort)
177-
178-
return self.proxyDeviceManager.ValidCaller(proxyId, addrPort.Addr())
179-
}
180-
181183
socksProxy := proxy.NewSocksProxy()
182184
socksProxy.ConnectDialWithRequest = connectDial
183185
socksProxy.ValidUser = validUser

proxy/run-builder.sh

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
env=main
44

5-
export GOEXPERIMENT=greenteagc; \
6-
export WARP_DOMAIN="bringyour.com"; \
7-
export WARP_SERVICE="proxy"; \
8-
export WARP_VERSION="0.0.0-local"; \
9-
export WARP_ENV="$env"; \
10-
export BRINGYOUR_POSTGRES_HOSTNAME="192.168.51.43"; \
11-
export BRINGYOUR_REDIS_HOSTNAME="192.168.51.43"; \
12-
go run . "$@"
5+
export GOEXPERIMENT=greenteagc
6+
export WARP_DOMAIN="bringyour.com"
7+
export WARP_SERVICE="proxy"
8+
export WARP_VERSION="0.0.0-local"
9+
export WARP_ENV="$env"
10+
export BRINGYOUR_POSTGRES_HOSTNAME="192.168.51.43"
11+
export BRINGYOUR_REDIS_HOSTNAME="192.168.51.43"
12+
while [ 1 ]; do
13+
go run . "$@"
14+
done

proxy/watchdog.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
"time"
10+
11+
"github.com/urnetwork/glog"
12+
"github.com/urnetwork/server"
13+
"github.com/urnetwork/server/jwt"
14+
"github.com/urnetwork/server/model"
15+
"github.com/urnetwork/server/session"
16+
)
17+
18+
type watchdog struct {
19+
ctx context.Context
20+
pollTimeout time.Duration
21+
}
22+
23+
func newWatchdog(ctx context.Context, pollTimeout time.Duration) *watchdog {
24+
w := &watchdog{
25+
ctx: ctx,
26+
pollTimeout: pollTimeout,
27+
}
28+
go server.HandleError(w.run, func() {
29+
os.Exit(1)
30+
})
31+
return w
32+
}
33+
34+
func (self *watchdog) run() {
35+
for {
36+
select {
37+
case <-self.ctx.Done():
38+
case <-time.After(self.pollTimeout):
39+
}
40+
41+
testNetworkId := server.RequireParseId("018c224b-909e-d3f3-b0bf-f40b7e11c5d7")
42+
testUserId := server.RequireParseId("018c224b-909e-d3f3-b0bf-f40b2f8f8cfd")
43+
44+
success := func() bool {
45+
testCtx, testCancel := context.WithCancel(self.ctx)
46+
defer testCancel()
47+
48+
testSession := &session.ClientSession{
49+
Ctx: testCtx,
50+
Cancel: testCancel,
51+
ClientAddress: "0.0.0.0:0",
52+
Header: map[string][]string{},
53+
ByJwt: &jwt.ByJwt{
54+
NetworkId: testNetworkId,
55+
UserId: testUserId,
56+
},
57+
}
58+
59+
result, err := model.AuthNetworkClient(
60+
&model.AuthNetworkClientArgs{
61+
Description: "proxy watchdog",
62+
DeviceSpec: "proxy watchdog",
63+
},
64+
testSession,
65+
)
66+
if err != nil {
67+
panic(err)
68+
}
69+
70+
clientId := *result.ClientId
71+
defer model.RemoveNetworkClient(
72+
&model.RemoveNetworkClientArgs{
73+
ClientId: clientId,
74+
},
75+
testSession,
76+
)
77+
78+
proxyDeviceConfig := &model.ProxyDeviceConfig{
79+
InitialDeviceState: &model.ProxyDeviceState{
80+
Location: model.GetConnectLocationForCountryCode(self.ctx, "us"),
81+
},
82+
}
83+
proxyDeviceConfig.ClientId = clientId
84+
model.CreateProxyDeviceConfig(self.ctx, proxyDeviceConfig)
85+
defer model.RemoveProxyDeviceConfig(testCtx, proxyDeviceConfig.ProxyId)
86+
signedProxyId := model.SignProxyId(proxyDeviceConfig.ProxyId)
87+
88+
httpProxyUrl, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", ListenHttpPort))
89+
if err != nil {
90+
panic(err)
91+
}
92+
93+
proxyConnectHeader := http.Header{}
94+
proxyConnectHeader.Add("Proxy-Authorization", fmt.Sprintf("Bearer %s", signedProxyId))
95+
96+
proxyHttpClient := &http.Client{
97+
Timeout: 120 * time.Second,
98+
Transport: &http.Transport{
99+
Proxy: http.ProxyURL(httpProxyUrl),
100+
ProxyConnectHeader: proxyConnectHeader,
101+
DisableKeepAlives: true,
102+
},
103+
}
104+
105+
n := 5
106+
success := false
107+
for i := range n {
108+
r, err := http.NewRequestWithContext(self.ctx, "GET", "https://api.bringyour.com/hello", nil)
109+
if err != nil {
110+
panic(err)
111+
}
112+
response, err := proxyHttpClient.Do(r)
113+
if err == nil && response.StatusCode == http.StatusOK {
114+
glog.Infof("[proxy][%d/%d]watchdog poll success\n", i+1, n)
115+
success = true
116+
break
117+
}
118+
if i+1 < n {
119+
glog.Infof("[proxy][%d/%d]watchdog poll failed err=%s. Will retry ...\n", i+1, n, err)
120+
} else {
121+
glog.Infof("[proxy][%d/%d]watchdog poll failed err=%s. Exiting.\n", i+1, n, err)
122+
}
123+
}
124+
return success
125+
}()
126+
select {
127+
case <-self.ctx.Done():
128+
return
129+
default:
130+
}
131+
if !success {
132+
os.Exit(1)
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)