package socket import ( "tunnel/pkg/server/env" "tunnel/pkg/server/queue" ) type deferSocket struct { S } type deferConn struct { sock *deferSocket wait chan bool env env.Env conn Conn } func newDeferSocket(proto, addr string) (S, error) { s, err := newDialSocket(proto, addr) if err != nil { return s, err } return &deferSocket{s}, nil } func (s *deferSocket) Open(env env.Env) (Conn, error) { c := &deferConn{ sock: s, wait: make(chan bool), env: env, } return c, nil } func (c *deferConn) String() string { return "defer" } func (c *deferConn) Send(wq queue.Q) error { if !<-c.wait { return nil } else { return c.conn.Send(wq) } } func (c *deferConn) Recv(rq queue.Q) error { b := <-rq if b == nil { c.wait <- false return nil } conn, err := c.sock.S.Open(c.env) if err != nil { c.wait <- false return err } c.conn = conn c.wait <- true q := queue.New() go func() { q <- b queue.Copy(rq, q) close(q) }() defer q.Dry() return c.conn.Recv(q) } func (c *deferConn) Close() (err error) { if c.conn != nil { err = c.conn.Close() } return }