summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/tunneld/main.go5
-rw-r--r--pkg/server/env.go9
-rw-r--r--pkg/server/env/env.go29
-rw-r--r--pkg/server/hook/proxy.go4
-rw-r--r--pkg/server/tunnel.go19
5 files changed, 59 insertions, 7 deletions
diff --git a/cmd/tunneld/main.go b/cmd/tunneld/main.go
index 908fcc3..995eb99 100644
--- a/cmd/tunneld/main.go
+++ b/cmd/tunneld/main.go
@@ -13,7 +13,6 @@ import (
"os/signal"
"os/user"
"path"
- "regexp"
"strconv"
"strings"
"syscall"
@@ -31,8 +30,6 @@ var (
const trimSize = 32
-var wordsRe = regexp.MustCompile("[[:^space:]]+")
-
func initLog() {
var logFlags int
@@ -134,7 +131,7 @@ func (p *parser) read(fp *os.File) error {
for nline := 1; scanner.Scan(); nline++ {
s := strings.SplitN(scanner.Text(), "#", 2)
t := strings.TrimSpace(s[0])
- args := wordsRe.FindAllString(s[0], -1)
+ args := strings.Fields(s[0])
if err := p.apply(args); err != nil {
return fmt.Errorf("%s:%d: %s: %w", fp.Name(), nline, t, err)
diff --git a/pkg/server/env.go b/pkg/server/env.go
index ea93a0d..8f27f70 100644
--- a/pkg/server/env.go
+++ b/pkg/server/env.go
@@ -22,6 +22,14 @@ func varSet(r *request) {
}
}
+func varPush(r *request) {
+ value := strings.Join(r.args[1:], " ")
+
+ if err := r.c.s.env.Push(r.args[0], value); err != nil {
+ r.Fatal(err)
+ }
+}
+
func varUnset(r *request) {
r.expect(1)
@@ -44,6 +52,7 @@ func varClear(r *request) {
func init() {
newCmd(varGet, "get")
newCmd(varSet, "set")
+ newCmd(varPush, "push")
newCmd(varUnset, "unset")
newCmd(varShow, "env")
newCmd(varClear, "clear")
diff --git a/pkg/server/env/env.go b/pkg/server/env/env.go
index 98ee231..b75d9a8 100644
--- a/pkg/server/env/env.go
+++ b/pkg/server/env/env.go
@@ -73,7 +73,7 @@ func (e Env) Has(key string) bool {
return ok
}
-func (e Env) Set(key string, value string) error {
+func validKeyValue(key string, value string) error {
if !isGoodName(key) {
return errBadVariable
}
@@ -82,6 +82,14 @@ func (e Env) Set(key string, value string) error {
return errEmptyVariable
}
+ return nil
+}
+
+func (e Env) Set(key string, value string) error {
+ if err := validKeyValue(key, value); err != nil {
+ return err
+ }
+
e.Lock()
defer e.Unlock()
@@ -92,6 +100,25 @@ func (e Env) Set(key string, value string) error {
return nil
}
+func (e Env) Push(key string, value string) error {
+ if err := validKeyValue(key, value); err != nil {
+ return err
+ }
+
+ e.Lock()
+ defer e.Unlock()
+
+ e.init()
+
+ if old, ok := e.m[key]; ok {
+ e.m[key] = old + "," + value
+ } else {
+ e.m[key] = value
+ }
+
+ return nil
+}
+
func (e *env) Del(key string) bool {
e.Lock()
defer e.Unlock()
diff --git a/pkg/server/hook/proxy.go b/pkg/server/hook/proxy.go
index 7da4c4a..ca8e3c8 100644
--- a/pkg/server/hook/proxy.go
+++ b/pkg/server/hook/proxy.go
@@ -24,6 +24,7 @@ type proxy struct {
addr string
auth string
c chan bool
+ env env.Env
}
func (p *proxy) Send(rq, wq queue.Q) error {
@@ -42,6 +43,8 @@ func (p *proxy) Send(rq, wq queue.Q) error {
return nil
}
+ p.env.Push("info", "-> " + p.addr)
+
return queue.Copy(rq, wq)
}
@@ -74,6 +77,7 @@ func (h *proxyHook) Open(env env.Env) (interface{}, error) {
addr: addr,
auth: h.auth,
c: make(chan bool),
+ env: env,
}
if p.auth == "" {
diff --git a/pkg/server/tunnel.go b/pkg/server/tunnel.go
index afd35d8..ae20c9b 100644
--- a/pkg/server/tunnel.go
+++ b/pkg/server/tunnel.go
@@ -229,8 +229,23 @@ func (s *stream) info() string {
d = s.until.Sub(s.since).Milliseconds()
}
- return fmt.Sprintf("%.3fs [%s] %d/%d -> %d/%d",
- float64(d)/1000.0, s.env.Get("info"),
+ var t string
+
+ switch {
+ case d < 60000:
+ t = fmt.Sprintf("%.3f", float64(d)/1000.0)
+ case d < 3600000:
+ m, d := d / 60000, d % 60000
+ t = fmt.Sprintf("%d:%06.3f", m, float64(d)/1000.0)
+ default:
+ h, d := d / 3600000, d % 3600000
+ m, d := d / 60000, d % 60000
+ t = fmt.Sprintf("%d:%02d:%06.3f", h, m, float64(d)/1000.0)
+ }
+
+ return fmt.Sprintf("[%s] %s %d/%d -> %d/%d",
+ s.env.Get("info"),
+ t,
s.m.in.tx,
s.m.in.rx,
s.m.out.rx,