package socket import ( "tunnel/pkg/server/env" "tunnel/pkg/server/queue" ) type deferSocket struct { dialSocket `opts:"inline"` } type deferConn struct { sock S wait chan bool env env.Env conn Conn } func (s *deferSocket) New(env env.Env) (Conn, error) { c := &deferConn{ sock: &s.dialSocket, 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.New(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 } func init() { register("defer", deferSocket{}) }