package tunnel import ( "io" "sync" ) type Connection struct { RX <-chan *DataFrame TX chan<- *DataFrame ID ID closed bool logger Logger } func (c *Connection) SetLogger(logger Logger) { c.logger = logger } func (c *Connection) Read(p []byte) (int, error) { df, ok := <-c.RX if !ok { return 0, c.Close() } c.logger.Trace("dataframe received: ", df) return df.Read(p) } func (c *Connection) Write(p []byte) (int, error) { var lock sync.Mutex lock.Lock() defer lock.Unlock() if c.closed { return 0, io.ErrClosedPipe } df := &DataFrame{ ID: c.ID, Type: TypeNormal, } n, err := df.Write(p) if err != nil { return 0, err } c.logger.Trace("dataframe send: ", df) c.TX <- df return n, nil } func (c *Connection) Close() error { defer c.logger.Tracef("connection closed") var lock sync.Mutex defer close(c.TX) if !c.closed { c.TX <- &DataFrame{ ID: c.ID, Type: TypeClosed, } } lock.Lock() c.closed = true lock.Unlock() return nil }