105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package communicator
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/TransX/log"
|
|
"github.com/TransX/tscipher"
|
|
)
|
|
|
|
type Receiver interface {
|
|
//SendData(carrier *Carrier) (n int, err error)
|
|
Receive() (n int, err error)
|
|
Close()
|
|
}
|
|
|
|
func NewNormalReceiver(carrier *tscipher.Carrier) *NormalReceiver {
|
|
r := new(NormalReceiver)
|
|
r.carrier = carrier
|
|
return r
|
|
}
|
|
|
|
type NormalReceiver struct {
|
|
Receiver
|
|
carrier *tscipher.Carrier
|
|
}
|
|
|
|
func (this *NormalReceiver) Receive() (n int, err error) {
|
|
carrier := this.carrier
|
|
wrapedPackage := carrier.GetReceiveBuff() //make([]byte, 0, cap(carrier.Cache))
|
|
var packageData []byte
|
|
var _rest []byte
|
|
cache, _ := carrier.Cache.Get()
|
|
for {
|
|
//首先检查这个是不是完整的包,是就返回好了,免得被阻塞
|
|
data, rest, err := tscipher.UnwrapPackage(wrapedPackage)
|
|
packageData = data
|
|
_rest = rest
|
|
if err, ok := err.(*tscipher.NotPackageError); len(wrapedPackage) >= 18 && ok {
|
|
log.Debug("return NotPackageError %s", carrier.AttachedTunnelID)
|
|
return 0, err
|
|
}
|
|
if err == nil {
|
|
//够一个完整的包
|
|
capBuff := cap(carrier.GetReceiveBuff())
|
|
_buff := make([]byte, 0, capBuff) //释放
|
|
_buff = append(_buff, _rest...)
|
|
carrier.SetReceiveBuff(_buff)
|
|
break
|
|
}
|
|
//如果读到的数据不够一个完整的包
|
|
if len(wrapedPackage) > 0 {
|
|
n, err = carrier.Conn.Read(cache)
|
|
if err != nil {
|
|
log.Error("ERROR %s", err.Error())
|
|
}
|
|
} else {
|
|
n, err = io.ReadAtLeast(carrier.Conn, cache, 18)
|
|
}
|
|
|
|
if err != nil {
|
|
n = 0
|
|
return n, err
|
|
}
|
|
wrapedPackage = append(wrapedPackage, cache[:n]...)
|
|
}
|
|
decrypted, err := carrier.Cipher.Decrypt(packageData)
|
|
if err != nil {
|
|
n = 0
|
|
return
|
|
}
|
|
n = len(decrypted)
|
|
carrier.Msg.Put(decrypted, n)
|
|
return
|
|
}
|
|
|
|
func (this *NormalReceiver) Close() {
|
|
this.carrier.Conn.Close()
|
|
}
|
|
|
|
func NewDirectReceiver(carrier *tscipher.Carrier) *DirectReceiver {
|
|
r := new(DirectReceiver)
|
|
r.carrier = carrier
|
|
return r
|
|
}
|
|
|
|
type DirectReceiver struct {
|
|
Receiver
|
|
carrier *tscipher.Carrier
|
|
}
|
|
|
|
func (this *DirectReceiver) Receive() (n int, err error) {
|
|
carrier := this.carrier
|
|
cache, _ := carrier.Cache.Get()
|
|
n, err = carrier.Conn.Read(cache)
|
|
if err != nil {
|
|
n = 0
|
|
}
|
|
carrier.Msg.Put(cache, n)
|
|
return
|
|
}
|
|
|
|
func (this *DirectReceiver) Close() {
|
|
this.carrier.Conn.Close()
|
|
}
|