Skip to content

Commit 02cebb9

Browse files
committed
Merge branch 'next'
2 parents 883a6ef + 9e8fde0 commit 02cebb9

File tree

13 files changed

+82
-97
lines changed

13 files changed

+82
-97
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
pull_request:
55
types: [opened, synchronize, reopened]
66
push:
7-
branches: [master]
7+
branches: ['*']
88
tags: ['*']
99

1010
jobs:

cmd/cmd.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,19 @@ func New() *cobra.Command {
7373
c := &cobra.Command{
7474
Use: "rsync-proxy",
7575
RunE: func(cmd *cobra.Command, args []string) error {
76-
switch {
77-
case reload:
78-
return SendReloadRequest(s.WebListenAddr, cmd.OutOrStdout(), cmd.ErrOrStderr())
79-
case version:
76+
if version {
8077
return printVersion(cmd.OutOrStdout())
8178
}
8279

8380
log.SetOutput(cmd.OutOrStdout(), cmd.ErrOrStderr())
8481

85-
err := s.LoadConfigFromFile()
82+
err := s.ReadConfigFromFile()
8683
if err != nil {
8784
return fmt.Errorf("load config: %w", err)
8885
}
86+
if reload {
87+
return SendReloadRequest(s.HTTPListenAddr, cmd.OutOrStdout(), cmd.ErrOrStderr())
88+
}
8989

9090
s.WriteTimeout = time.Minute
9191
s.ReadTimeout = time.Minute
@@ -98,9 +98,7 @@ func New() *cobra.Command {
9898
},
9999
}
100100
flags := c.Flags()
101-
flags.StringVar(&s.ListenAddr, "listen-addr", "0.0.0.0:9527", "Address to listen on for reverse proxy")
102-
flags.StringVar(&s.WebListenAddr, "web.listen-addr", "127.0.0.1:9528", "Address to listen on for API")
103-
flags.StringVar(&s.ConfigPath, "config", "/etc/rsync-proxy/config.toml", "Path to config file")
101+
flags.StringVarP(&s.ConfigPath, "config", "c", "/etc/rsync-proxy/config.toml", "Path to config file")
104102
flags.BoolVar(&reload, "reload", false, "Inform server to reload config")
105103
flags.BoolVarP(&version, "version", "V", false, "Print version and exit")
106104

dist/config.example.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
# Example config
22

33
[proxy]
4+
listen = "0.0.0.0:873"
5+
listen_http = "127.0.0.1:9528"
46
motd = "Served by rsync-proxy (https://github.com/ustclug/rsync-proxy)"
57

68
[upstreams.u1]
7-
host = "127.0.0.1"
8-
port = 1234
9+
address = "127.0.0.1:1234"
910
modules = ["foo"]
1011

1112
[upstreams.u2]
12-
host = "192.168.0.10"
13-
port = 1235
13+
address = "192.168.0.10:1235"
1414
modules = ["bar"]
1515

1616
[upstreams.u3]
17-
host = "rsync.example.internal"
18-
port = 1235
17+
address = "rsync.example.internal:1235"
1918
modules = ["baz"]

dist/rsync-proxy.service

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Restart=on-failure
66
StartLimitInterval=10s
77

88
ExecStartPre=mkdir -p /var/log/rsync-proxy/
9-
ExecStart=/usr/local/bin/rsync-proxy -v=3 --config=/etc/rsync-proxy/config.toml --listen-addr=0.0.0.0:873 --web.listen-addr=127.0.0.1:9528
10-
ExecReload=/usr/local/bin/rsync-proxy --web.listen-addr=127.0.0.1:9528 --reload
9+
ExecStart=/usr/local/bin/rsync-proxy -v=3 --config=/etc/rsync-proxy/config.toml
10+
ExecReload=/usr/local/bin/rsync-proxy --config=/etc/rsync-proxy/config.toml --reload
1111
StandardOutput=append:/var/log/rsync-proxy/stdout.log
1212
StandardError=append:/var/log/rsync-proxy/stderr.log
1313

pkg/server/config.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,22 @@ import (
1010
)
1111

1212
type Upstream struct {
13-
Host string `toml:"host"`
14-
Port int `toml:"port"`
13+
Address string `toml:"address"`
1514
Modules []string `toml:"modules"`
1615
}
1716

1817
type ProxySettings struct {
19-
Motd string `toml:"motd"`
18+
Listen string `toml:"listen"`
19+
ListenHTTP string `toml:"listen_http"`
20+
Motd string `toml:"motd"`
2021
}
2122

2223
type Config struct {
2324
Proxy ProxySettings `toml:"proxy"`
2425
Upstreams map[string]*Upstream `toml:"upstreams"`
2526
}
2627

27-
func (s *Server) LoadConfig(r io.Reader) error {
28+
func (s *Server) ReadConfig(r io.Reader) error {
2829
log.V(3).Infof("[INFO] loading config")
2930

3031
dec := toml.NewDecoder(r)
@@ -33,17 +34,14 @@ func (s *Server) LoadConfig(r io.Reader) error {
3334
if err != nil {
3435
return err
3536
}
36-
37-
s.Upstreams = c.Upstreams
38-
s.Motd = c.Proxy.Motd
39-
return s.complete()
37+
return s.loadConfig(&c)
4038
}
4139

42-
func (s *Server) LoadConfigFromFile() error {
40+
func (s *Server) ReadConfigFromFile() error {
4341
f, err := os.Open(s.ConfigPath)
4442
if err != nil {
4543
return err
4644
}
4745
defer f.Close()
48-
return s.LoadConfig(f)
46+
return s.ReadConfig(f)
4947
}

pkg/server/config_test.go

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,22 @@ import (
66
"testing"
77
)
88

9-
func TestLoadConfig(t *testing.T) {
9+
func TestReadConfig(t *testing.T) {
1010
s := New()
1111
configContent := `
1212
[upstreams.u1]
13-
host = "127.0.0.1"
14-
port = 1234
13+
address = "127.0.0.1:1234"
1514
modules = ["foo1", "foo2"]
1615
1716
[upstreams.u2]
18-
host = "127.0.0.1"
19-
port = 1235
17+
address = "127.0.0.1:1235"
2018
modules = ["bar1"]
2119
2220
[upstreams.u3]
23-
host = "example.com"
24-
port = 1235
21+
address = "example.com:1235"
2522
modules = ["bar2"]
2623
`
27-
err := s.LoadConfig(strings.NewReader(configContent))
24+
err := s.ReadConfig(strings.NewReader(configContent))
2825
if err != nil {
2926
t.Fatalf("Load config: %s", err)
3027
}
@@ -43,20 +40,18 @@ func TestDuplicatedModulesInConfig(t *testing.T) {
4340
s := New()
4441
configContent := `
4542
[upstreams.u1]
46-
host = "127.0.0.1"
47-
port = 1234
43+
address = "127.0.0.1:1234"
4844
modules = ["foo1", "foo2"]
4945
5046
[upstreams.u2]
51-
host = "127.0.0.1"
52-
port = 1235
47+
address = "127.0.0.1:1235"
5348
modules = ["foo1"]
5449
`
55-
err := s.LoadConfig(strings.NewReader(configContent))
50+
err := s.ReadConfig(strings.NewReader(configContent))
5651
if err == nil {
5752
t.Fatalf("Unexpected success")
5853
}
59-
if !strings.Contains(err.Error(), "duplicated module name") {
54+
if !strings.Contains(err.Error(), "duplicate module name") {
6055
t.Errorf("Unexpected error. Got: %s", err)
6156
}
6257
}
@@ -68,11 +63,10 @@ func TestLoadMotdInConfig(t *testing.T) {
6863
motd = "Proudly served by rsync-proxy\ntest newline"
6964
7065
[upstreams.u1]
71-
host = "127.0.0.1"
72-
port = 1234
66+
address = "127.0.0.1:1234"
7367
modules = ["foo1", "foo2"]
7468
`
75-
err := s.LoadConfig(strings.NewReader(configContent))
69+
err := s.ReadConfig(strings.NewReader(configContent))
7670
if err != nil {
7771
t.Fatalf("Load config: %s", err)
7872
}

pkg/server/server.go

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"io"
1010
"net"
1111
"net/http"
12+
"os"
1213
"sort"
13-
"strconv"
1414
"sync"
1515
"sync/atomic"
1616
"time"
@@ -33,11 +33,10 @@ const lineFeed = '\n'
3333
type Server struct {
3434
// --- Options section
3535
// Listen Address
36-
ListenAddr string
37-
WebListenAddr string
38-
ConfigPath string
39-
// name -> upstream
40-
Upstreams map[string]*Upstream
36+
ListenAddr string
37+
HTTPListenAddr string
38+
ConfigPath string
39+
4140
ReadTimeout time.Duration
4241
WriteTimeout time.Duration
4342
// motd
@@ -53,14 +52,14 @@ type Server struct {
5352
activeConnCount atomic.Int64
5453
connIndex atomic.Uint64
5554

56-
TCPListener net.Listener
57-
HTTPListener net.Listener
55+
TCPListener *net.TCPListener
56+
HTTPListener *net.TCPListener
5857
}
5958

6059
func New() *Server {
6160
return &Server{
6261
bufPool: sync.Pool{
63-
New: func() interface{} {
62+
New: func() any {
6463
buf := make([]byte, TCPBufferSize)
6564
return &buf
6665
},
@@ -69,33 +68,33 @@ func New() *Server {
6968
}
7069
}
7170

72-
func (s *Server) complete() error {
73-
if len(s.Upstreams) == 0 {
71+
func (s *Server) loadConfig(c *Config) error {
72+
if len(c.Upstreams) == 0 {
7473
return fmt.Errorf("no upstream found")
7574
}
7675

7776
modules := map[string]string{}
78-
for upstreamName, v := range s.Upstreams {
79-
addr := net.JoinHostPort(v.Host, strconv.Itoa(v.Port))
77+
for upstreamName, v := range c.Upstreams {
78+
addr := v.Address
8079
_, err := net.ResolveTCPAddr("tcp", addr)
8180
if err != nil {
8281
return fmt.Errorf("resolve address: %w, upstream=%s, address=%s", err, upstreamName, addr)
8382
}
8483
for _, moduleName := range v.Modules {
8584
if _, ok := modules[moduleName]; ok {
86-
return fmt.Errorf("duplicated module name: %s, upstream=%s", moduleName, upstreamName)
85+
return fmt.Errorf("duplicate module name: %s, upstream=%s", moduleName, upstreamName)
8786
}
8887
modules[moduleName] = addr
8988
}
9089
}
9190

9291
s.reloadLock.Lock()
92+
// s.ListenAddr = c.Proxy.Listen
93+
// s.HTTPListenAddr = c.Proxy.ListenHTTP
94+
s.Motd = c.Proxy.Motd
9395
s.modules = modules
9496
s.reloadLock.Unlock()
9597

96-
// .Upstreams is no longer used, reclaims the memory
97-
s.Upstreams = nil
98-
9998
return nil
10099
}
101100

@@ -255,12 +254,12 @@ func (s *Server) relay(ctx context.Context, downConn *net.TCPConn) error {
255254
return nil
256255
}
257256

258-
func (s *Server) handleConn(ctx context.Context, conn net.Conn) {
257+
func (s *Server) handleConn(ctx context.Context, conn *net.TCPConn) {
259258
s.activeConnCount.Add(1)
260259
defer s.activeConnCount.Add(-1)
261260
_ = s.connIndex.Add(1)
262-
downConn := conn.(*net.TCPConn)
263-
err := s.relay(ctx, downConn)
261+
262+
err := s.relay(ctx, conn)
264263
if err != nil {
265264
log.V(2).Errorf("[WARN] handleConn: %s", err)
266265
}
@@ -278,7 +277,7 @@ func (s *Server) runHTTPServer() error {
278277
Message string `json:"message"`
279278
}
280279

281-
err := s.LoadConfigFromFile()
280+
err := s.ReadConfigFromFile()
282281
if err != nil {
283282
log.Errorf("[ERROR] Load config: %s", err)
284283
w.WriteHeader(http.StatusInternalServerError)
@@ -290,17 +289,20 @@ func (s *Server) runHTTPServer() error {
290289
_ = json.NewEncoder(w).Encode(&resp)
291290
})
292291

293-
mux.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) {
292+
mux.HandleFunc("/telegraf", func(w http.ResponseWriter, r *http.Request) {
294293
if r.Method != http.MethodGet {
295294
w.WriteHeader(http.StatusMethodNotAllowed)
296295
return
297296
}
298297

299-
var resp struct {
300-
Count int64 `json:"count"`
298+
timestamp := time.Now().Truncate(time.Second).UnixNano()
299+
count := s.GetActiveConnectionCount()
300+
hostname, err := os.Hostname()
301+
if err != nil {
302+
hostname = "(unknown)"
301303
}
302-
resp.Count = s.GetActiveConnectionCount()
303-
_ = json.NewEncoder(w).Encode(&resp)
304+
// https://docs.influxdata.com/influxdb/latest/reference/syntax/line-protocol/
305+
_, _ = fmt.Fprintf(w, "rsync-proxy,host=%q count=%d %d\n", hostname, count, timestamp)
304306
})
305307

306308
return http.Serve(s.HTTPListener, &mux)
@@ -314,15 +316,15 @@ func (s *Server) Listen() error {
314316
s.ListenAddr = l1.Addr().String()
315317
log.V(3).Infof("[INFO] Rsync proxy listening on %s", s.ListenAddr)
316318

317-
l2, err := net.Listen("tcp", s.WebListenAddr)
319+
l2, err := net.Listen("tcp", s.HTTPListenAddr)
318320
if err != nil {
319321
return fmt.Errorf("create http listener: %w", err)
320322
}
321-
s.WebListenAddr = l2.Addr().String()
322-
log.V(3).Infof("[INFO] HTTP server listening on %s", s.WebListenAddr)
323+
s.HTTPListenAddr = l2.Addr().String()
324+
log.V(3).Infof("[INFO] HTTP server listening on %s", s.HTTPListenAddr)
323325

324-
s.TCPListener = l1
325-
s.HTTPListener = l2
326+
s.TCPListener = l1.(*net.TCPListener)
327+
s.HTTPListener = l2.(*net.TCPListener)
326328
return nil
327329
}
328330

@@ -336,14 +338,14 @@ func (s *Server) Close() {
336338
}
337339

338340
func (s *Server) Run() error {
339-
errCh := make(chan error)
341+
errC := make(chan error)
340342
go func() {
341343
err := s.runHTTPServer()
342344
if err != nil {
343345
if errors.Is(err, net.ErrClosed) {
344346
return
345347
}
346-
errCh <- fmt.Errorf("run http server: %w", err)
348+
errC <- fmt.Errorf("run http server: %w", err)
347349
}
348350
}()
349351

@@ -352,12 +354,12 @@ func (s *Server) Run() error {
352354

353355
for {
354356
select {
355-
case err := <-errCh:
357+
case err := <-errC:
356358
return err
357359
default:
358360
}
359361

360-
conn, err := s.TCPListener.Accept()
362+
conn, err := s.TCPListener.AcceptTCP()
361363
if err != nil {
362364
if errors.Is(err, net.ErrClosed) {
363365
return nil

pkg/server/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func startServer(t *testing.T) *Server {
2020
addr = "127.0.0.1:0"
2121
timeout = time.Second
2222
)
23-
srv.WebListenAddr = addr
23+
srv.HTTPListenAddr = addr
2424
srv.ListenAddr = addr
2525
srv.ReadTimeout = timeout
2626
srv.WriteTimeout = timeout

0 commit comments

Comments
 (0)