github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/warpfront/Session.go (about)

     1  package warpfront
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"net"
     8  	"sync"
     9  	"time"
    10  )
    11  
    12  type session struct {
    13  	rx  chan []byte
    14  	tx  chan []byte
    15  	ded chan bool
    16  	buf *bytes.Buffer
    17  
    18  	readDeadline  *time.Timer
    19  	writeDeadline *time.Timer
    20  
    21  	once sync.Once
    22  }
    23  
    24  func newSession() *session {
    25  	return &session{
    26  		rx:  make(chan []byte),
    27  		tx:  make(chan []byte),
    28  		ded: make(chan bool),
    29  		buf: new(bytes.Buffer),
    30  	}
    31  }
    32  
    33  func (sess *session) readDeadlineCh() <-chan time.Time {
    34  	if sess.readDeadline != nil {
    35  		return sess.readDeadline.C
    36  	}
    37  	return nil
    38  }
    39  
    40  func (sess *session) writeDeadlineCh() <-chan time.Time {
    41  	if sess.writeDeadline != nil {
    42  		return sess.writeDeadline.C
    43  	}
    44  	return nil
    45  }
    46  
    47  func (sess *session) Write(pkt []byte) (int, error) {
    48  	cpy := make([]byte, len(pkt))
    49  	copy(cpy, pkt)
    50  	select {
    51  	case sess.tx <- cpy:
    52  		return len(pkt), nil
    53  	case <-sess.writeDeadlineCh():
    54  		return 0, errors.New("write timeout")
    55  	case <-sess.ded:
    56  		return 0, io.ErrClosedPipe
    57  	}
    58  }
    59  
    60  func (sess *session) Read(p []byte) (int, error) {
    61  	if sess.buf.Len() > 0 {
    62  		return sess.buf.Read(p)
    63  	}
    64  	select {
    65  	case bts := <-sess.rx:
    66  		sess.buf.Write(bts)
    67  		return sess.Read(p)
    68  	case <-sess.readDeadlineCh():
    69  		return 0, errors.New("read timeout")
    70  	case <-sess.ded:
    71  		return 0, io.ErrClosedPipe
    72  	}
    73  }
    74  
    75  func (sess *session) Close() error {
    76  	sess.once.Do(func() {
    77  		close(sess.ded)
    78  	})
    79  	return nil
    80  }
    81  
    82  func (sess *session) LocalAddr() net.Addr {
    83  	return &wfAddr{}
    84  }
    85  
    86  func (sess *session) RemoteAddr() net.Addr {
    87  	return &wfAddr{}
    88  }
    89  
    90  func (sess *session) SetDeadline(t time.Time) error {
    91  	sess.SetWriteDeadline(t)
    92  	sess.SetReadDeadline(t)
    93  	return nil
    94  }
    95  
    96  func (sess *session) SetWriteDeadline(t time.Time) error {
    97  	if t == (time.Time{}) {
    98  		sess.writeDeadline = nil
    99  	} else {
   100  		if sess.writeDeadline != nil {
   101  			sess.writeDeadline.Stop()
   102  		}
   103  		sess.writeDeadline = time.NewTimer(t.Sub(time.Now()))
   104  	}
   105  	return nil
   106  }
   107  
   108  func (sess *session) SetReadDeadline(t time.Time) error {
   109  	if t == (time.Time{}) {
   110  		sess.readDeadline = nil
   111  	} else {
   112  		if sess.readDeadline != nil {
   113  			sess.readDeadline.Stop()
   114  		}
   115  		sess.readDeadline = time.NewTimer(t.Sub(time.Now()))
   116  	}
   117  	return nil
   118  }
   119  
   120  type wfAddr struct{}
   121  
   122  func (wfAddr) String() string {
   123  	return "warpfront"
   124  }
   125  
   126  func (wfAddr) Network() string {
   127  	return "warpfront"
   128  }