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 }