summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/server/automap.go31
-rw-r--r--pkg/server/tunnel.go118
2 files changed, 135 insertions, 14 deletions
diff --git a/pkg/server/automap.go b/pkg/server/automap.go
index 15cafe4..cf4de7d 100644
--- a/pkg/server/automap.go
+++ b/pkg/server/automap.go
@@ -1,12 +1,37 @@
package server
-type automap map[int]interface{}
+import (
+ "errors"
+ "fmt"
+)
-func (m automap) add(v interface{}) int {
- for k := 0;; k++ {
+type automap map[string]interface{}
+
+var errExists = errors.New("already exists")
+var errNotFound = errors.New("no such entry")
+
+func (m automap) add(v interface{}) string {
+ for n := 1;; n++ {
+ k := fmt.Sprintf("%d", n)
if _, ok := m[k]; !ok {
m[k] = v
return k
}
}
}
+
+func (m automap) rename(old string, new string) (interface{}, error) {
+ if _, ok := m[old]; !ok {
+ return nil, errNotFound
+ }
+
+ if _, ok := m[new]; ok {
+ return nil, errExists
+ }
+
+ v := m[old]
+ m[new] = v
+
+ delete(m, old)
+ return v, nil
+}
diff --git a/pkg/server/tunnel.go b/pkg/server/tunnel.go
index b1c3fe8..04f838b 100644
--- a/pkg/server/tunnel.go
+++ b/pkg/server/tunnel.go
@@ -23,7 +23,7 @@ type stream struct {
}
type tunnel struct {
- id int
+ id string
args string
streams map[int]*stream
@@ -32,6 +32,9 @@ type tunnel struct {
nextSid int
+ quit chan struct{}
+ done chan struct{}
+
in, out socket.S
m []module.M
}
@@ -41,24 +44,54 @@ func (s *stream) String() string {
}
func (t *tunnel) String() string {
- return fmt.Sprintf("tunnel(%d)", t.id)
+ return fmt.Sprintf("tunnel(%s)", t.id)
}
+/* FIXME close streams also */
func (t *tunnel) Close() {
+ close(t.quit)
t.in.Close()
t.out.Close()
+ <-t.done
+
+ log.Println(t, "delete")
+}
+
+func (t *tunnel) isQuit() bool {
+ select {
+ case <-t.quit:
+ return true
+ default:
+ return false
+ }
}
-func (t *tunnel) run() {
+func (t *tunnel) serve() {
+ var wg sync.WaitGroup
+
for {
if in, err := t.in.Open(); err != nil {
+ if t.isQuit() {
+ break
+ }
+
log.Println(t, err)
time.Sleep(5 * time.Second)
} else {
log.Println(t, "open", in)
- go t.run2(in)
+
+ wg.Add(1)
+
+ go func () {
+ t.handle(in)
+ wg.Done()
+ }()
}
}
+
+ wg.Wait()
+
+ close(t.done)
}
func (t *tunnel) newStream(in, out socket.Channel) *stream {
@@ -123,7 +156,9 @@ func (s *stream) watchPipe(rq, wq queue.Q, f func (rq, wq queue.Q) error) {
}()
}
-func (t *tunnel) run2(in socket.Channel) {
+func (t *tunnel) handle(in socket.Channel) {
+ log.Println(t, "handle")
+
out, err := t.out.Open()
if err != nil {
log.Println(t, err)
@@ -178,6 +213,8 @@ func newTunnel(args []string) (*tunnel, error) {
t := &tunnel{
args: strings.Join(args, " "),
+ quit: make(chan struct{}),
+ done: make(chan struct{}),
in: in,
out: out,
streams: make(map[int]*stream),
@@ -216,34 +253,89 @@ func newTunnel(args []string) (*tunnel, error) {
return nil, fmt.Errorf("bad '-' usage")
}
- go t.run()
+ go t.serve()
return t, nil
}
+func isOkTunnelName(s string) bool {
+ return s != ""
+}
+
func tunnelAdd(r *request) {
- if r.argc < 2 {
+ args := r.args
+ name := ""
+
+ if len(args) >= 2 {
+ if args[0] == "name" {
+ name = args[1]
+ if !isOkTunnelName(name) {
+ r.Fatal("bad name")
+ }
+
+ if _, ok := r.c.s.tunnels[name]; ok {
+ r.Fatal("already exists")
+ }
+
+ args = args[2:]
+ }
+ }
+
+ if len(args) < 2 {
r.Fatal("not enough args")
}
- t, err := newTunnel(r.args)
+ t, err := newTunnel(args)
if err != nil {
r.Fatal(err)
}
+ if name == "" {
+ t.id = r.c.s.tunnels.add(t)
+ } else {
+ t.id = name
+ r.c.s.tunnels[t.id] = t
+ }
+
log.Println(r.c, r, t, "create")
+}
- t.id = r.c.s.tunnels.add(t)
+func tunnelDel(r *request) {
+ r.expect(1)
+
+ id := r.args[0]
+
+ if t, ok := r.c.s.tunnels[id]; !ok {
+ r.Fatal("no such entry")
+ } else {
+ t.(*tunnel).Close()
+ delete(r.c.s.tunnels, id)
+ }
+}
+
+func tunnelRename(r *request) {
+ r.expect(2)
+
+ old, new := r.args[0], r.args[1]
+ if !isOkTunnelName(new) {
+ r.Fatal("bad name")
+ }
+
+ if t, err := r.c.s.tunnels.rename(old, new); err != nil {
+ r.Fatal(err)
+ } else {
+ t.(*tunnel).id = new
+ }
}
func foreachTunnel(m automap, f func (t *tunnel)) {
- var keys []int
+ var keys []string
for k := range m {
keys = append(keys, k)
}
- sort.Ints(keys)
+ sort.Strings(keys)
for _, k := range keys {
f(m[k].(*tunnel))
@@ -289,6 +381,10 @@ func streamShow(r *request) {
func init() {
newCmd(tunnelAdd, "add")
+ newCmd(tunnelDel, "del")
+
+ newCmd(tunnelRename, "rename")
+
newCmd(tunnelShow, "show")
newCmd(streamShow, "stream show")
}