summaryrefslogtreecommitdiff
path: root/pkg/server/socket/auto.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/server/socket/auto.go')
-rw-r--r--pkg/server/socket/auto.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/pkg/server/socket/auto.go b/pkg/server/socket/auto.go
new file mode 100644
index 0000000..97bc625
--- /dev/null
+++ b/pkg/server/socket/auto.go
@@ -0,0 +1,80 @@
+package socket
+
+import (
+ "tunnel/pkg/server/env"
+ "tunnel/pkg/server/queue"
+)
+
+type autoSocket struct {
+ S
+}
+
+type autoChannel struct {
+ s *autoSocket
+ c chan Channel
+ e env.Env
+}
+
+func newAutoSocket(proto, addr string) (S, error) {
+ s, err := newDialSocket(proto, addr)
+ if err != nil {
+ return s, err
+ }
+
+ return &autoSocket{s}, nil
+}
+
+func (s *autoSocket) Open(env env.Env) (Channel, error) {
+ c := &autoChannel{
+ s: s,
+ c: make(chan Channel),
+ e: env,
+ }
+
+ return c, nil
+}
+
+func (c *autoChannel) String() string {
+ return "auto"
+}
+
+func (c *autoChannel) Send(wq queue.Q) error {
+ if x := <-c.c; x == nil {
+ return nil
+ } else {
+ return x.Send(wq)
+ }
+}
+
+func (c *autoChannel) Recv(rq queue.Q) error {
+ b := <-rq
+ if b == nil {
+ close(c.c)
+ return nil
+ }
+
+ x, err := c.s.S.Open(c.e)
+ if err != nil {
+ close(c.c)
+ return err
+ }
+
+ c.c <- x
+
+ q := queue.New()
+
+ go func() {
+ q <- b
+ queue.Copy(rq, q)
+ close(q)
+ }()
+
+ defer q.Dry()
+
+ return x.Recv(q)
+}
+
+/* TODO */
+func (c *autoChannel) Close() error {
+ return nil
+}