package tunnel
import (
"io"
"sync"
)
type Connection struct {
RX <-chan *DataFrame
TX chan<- *DataFrame
ID ID
closed bool
}
func (c *Connection) Read(p []byte) (int, error) {
df, ok := <-c.RX
if !ok {
return 0, c.Close()
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.TX <- df
return n, nil
func (c *Connection) Close() error {
defer close(c.TX)
if !c.closed {
c.TX <- &DataFrame{
Type: TypeClosed,
c.closed = true
lock.Unlock()
return nil