This commit is contained in:
esrrhs 2019-10-26 12:01:30 +08:00
parent ff3daaed0f
commit a13cd98e29
8 changed files with 265 additions and 103 deletions

View File

@ -1,6 +1,7 @@
package pingtunnel package pingtunnel
import ( import (
"github.com/esrrhs/go-engine/src/common"
"github.com/esrrhs/go-engine/src/loggo" "github.com/esrrhs/go-engine/src/loggo"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
@ -189,7 +190,7 @@ func (p *Client) AcceptTcp() error {
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error accept tcp %s", err) loggo.Info("Error accept tcp %s", err)
continue continue
} }
} }
@ -217,15 +218,21 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn) {
bytes := make([]byte, 10240) bytes := make([]byte, 10240)
tcpActiveRecvTime := time.Now()
tcpActiveSendTime := time.Now()
for { for {
left := clientConn.fm.GetSendBufferLeft() now := time.Now()
if left >= len(bytes) {
left := common.MinOfInt(clientConn.fm.GetSendBufferLeft(), len(bytes))
if left > 0 {
conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100)) conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
n, err := conn.Read(bytes) n, err := conn.Read(bytes[0:left])
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error read tcp %s %s %s", uuid, tcpsrcaddr.String(), err) loggo.Info("Error read tcp %s %s %s", uuid, tcpsrcaddr.String(), err)
clientConn.fm.Close()
break break
} }
} }
@ -237,38 +244,33 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn) {
clientConn.fm.Update() clientConn.fm.Update()
sendlist := clientConn.fm.getSendList() sendlist := clientConn.fm.getSendList()
if sendlist.Len() > 0 {
now := time.Now()
clientConn.activeSendTime = now clientConn.activeSendTime = now
for e := sendlist.Front(); e != nil; e = e.Next() { for e := sendlist.Front(); e != nil; e = e.Next() {
f := e.Value.(*Frame) f := e.Value.(*Frame)
mb, err := proto.Marshal(f) mb, err := proto.Marshal(f)
if err != nil { if err != nil {
loggo.Error("Error tcp Marshal %s %s %s", uuid, tcpsrcaddr.String(), err) loggo.Error("Error tcp Marshal %s %s %s", uuid, tcpsrcaddr.String(), err)
continue continue
} }
p.sequence++ p.sequence++
p.sendPacket++
p.sendPacketSize += (uint64)(len(mb))
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb, sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb,
SEND_PROTO, RECV_PROTO, p.key, SEND_PROTO, RECV_PROTO, p.key,
p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems) p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems)
p.sendPacket++
p.sendPacketSize += (uint64)(len(mb))
}
} }
if clientConn.fm.GetRecvBufferSize() > 0 { if clientConn.fm.GetRecvBufferSize() > 0 {
rr := clientConn.fm.GetRecvReadLineBuffer() rr := clientConn.fm.GetRecvReadLineBuffer()
conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)) conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100))
n, err := conn.Write(rr) n, err := conn.Write(rr)
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error write tcp %s %s %s", uuid, tcpsrcaddr.String(), err) loggo.Info("Error write tcp %s %s %s", uuid, tcpsrcaddr.String(), err)
clientConn.fm.Close()
break break
} }
} }
@ -279,10 +281,66 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn) {
diffrecv := now.Sub(clientConn.activeRecvTime) diffrecv := now.Sub(clientConn.activeRecvTime)
diffsend := now.Sub(clientConn.activeSendTime) diffsend := now.Sub(clientConn.activeSendTime)
if diffrecv > time.Second*(time.Duration(p.timeout)) || diffsend > time.Second*(time.Duration(p.timeout)) { tcpdiffrecv := now.Sub(tcpActiveRecvTime)
tcpdiffsend := now.Sub(tcpActiveSendTime)
if diffrecv > time.Second*(time.Duration(p.timeout)) || diffsend > time.Second*(time.Duration(p.timeout)) ||
tcpdiffrecv > time.Second*(time.Duration(p.timeout)) || tcpdiffsend > time.Second*(time.Duration(p.timeout)) {
loggo.Info("close inactive conn %s %s", clientConn.id, clientConn.tcpaddr.String()) loggo.Info("close inactive conn %s %s", clientConn.id, clientConn.tcpaddr.String())
clientConn.fm.Close()
break break
} }
if clientConn.fm.IsRemoteClosed() {
loggo.Info("closed by remote conn %s %s", clientConn.id, clientConn.tcpaddr.String())
clientConn.fm.Close()
break
}
}
startCloseTime := time.Now()
for {
now := time.Now()
clientConn.fm.Update()
sendlist := clientConn.fm.getSendList()
for e := sendlist.Front(); e != nil; e = e.Next() {
f := e.Value.(*Frame)
mb, _ := proto.Marshal(f)
p.sequence++
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb,
SEND_PROTO, RECV_PROTO, p.key,
p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems)
p.sendPacket++
p.sendPacketSize += (uint64)(len(mb))
}
nodatarecv := true
if clientConn.fm.GetRecvBufferSize() > 0 {
rr := clientConn.fm.GetRecvReadLineBuffer()
conn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100))
n, _ := conn.Write(rr)
if n > 0 {
clientConn.fm.SkipRecvBuffer(n)
nodatarecv = false
}
}
diffclose := now.Sub(startCloseTime)
timeout := diffclose > time.Second*(time.Duration(p.timeout))
remoteclosed := clientConn.fm.IsRemoteClosed()
if timeout {
loggo.Info("close conn had timeout %s %s", clientConn.id, clientConn.tcpaddr.String())
break
}
if remoteclosed && nodatarecv {
loggo.Info("remote conn had closed %s %s", clientConn.id, clientConn.tcpaddr.String())
break
}
time.Sleep(time.Millisecond * 100)
} }
loggo.Info("close tcp conn %s %s", clientConn.id, clientConn.tcpaddr.String()) loggo.Info("close tcp conn %s %s", clientConn.id, clientConn.tcpaddr.String())
@ -302,7 +360,7 @@ func (p *Client) Accept() error {
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error read udp %s", err) loggo.Info("Error read udp %s", err)
continue continue
} }
} }
@ -379,7 +437,7 @@ func (p *Client) processPacket(packet *Packet) {
} else { } else {
_, err := p.listenConn.WriteToUDP(packet.my.Data, addr) _, err := p.listenConn.WriteToUDP(packet.my.Data, addr)
if err != nil { if err != nil {
loggo.Error("WriteToUDP Error read udp %s", err) loggo.Info("WriteToUDP Error read udp %s", err)
clientConn.close = true clientConn.close = true
return return
} }

View File

@ -76,7 +76,7 @@ func main() {
loggo.Info("key %d", *key) loggo.Info("key %d", *key)
if *t == "server" { if *t == "server" {
s, err := pingtunnel.NewServer(*timeout, *key) s, err := pingtunnel.NewServer(*key)
if err != nil { if err != nil {
loggo.Error("ERROR: %s", err.Error()) loggo.Error("ERROR: %s", err.Error())
return return

View File

@ -22,6 +22,9 @@ type FrameMgr struct {
recvwin *list.List recvwin *list.List
recvlist *list.List recvlist *list.List
recvid int recvid int
close bool
remoteclosed bool
} }
func NewFrameMgr(buffersize int, windowsize int, resend_timems int) *FrameMgr { func NewFrameMgr(buffersize int, windowsize int, resend_timems int) *FrameMgr {
@ -33,7 +36,8 @@ func NewFrameMgr(buffersize int, windowsize int, resend_timems int) *FrameMgr {
recvlock: &sync.Mutex{}, recvlock: &sync.Mutex{},
windowsize: windowsize, resend_timems: resend_timems, windowsize: windowsize, resend_timems: resend_timems,
sendwin: list.New(), sendlist: list.New(), sendid: 0, sendwin: list.New(), sendlist: list.New(), sendid: 0,
recvwin: list.New(), recvlist: list.New(), recvid: 0} recvwin: list.New(), recvlist: list.New(), recvid: 0,
close: false, remoteclosed: false}
return fm return fm
} }
@ -95,6 +99,18 @@ func (fm *FrameMgr) cutSendBufferToWindow() {
fm.sendwin.PushBack(f) fm.sendwin.PushBack(f)
} }
if fm.sendb.Empty() && fm.close {
f := &Frame{Type: (int32)(Frame_DATA), Resend: false, Sendtime: 0,
Id: (int32)(fm.sendid),
Data: make([]byte, 0)}
fm.sendwin.PushBack(f)
fm.sendid++
if fm.sendid >= FRAME_MAX_ID {
fm.sendid = 0
}
}
} }
func (fm *FrameMgr) calSendList() { func (fm *FrameMgr) calSendList() {
@ -116,7 +132,6 @@ func (fm *FrameMgr) getSendList() *list.List {
func (fm *FrameMgr) OnRecvFrame(f *Frame) { func (fm *FrameMgr) OnRecvFrame(f *Frame) {
fm.recvlock.Lock() fm.recvlock.Lock()
defer fm.recvlock.Unlock() defer fm.recvlock.Unlock()
fm.recvlist.PushBack(f) fm.recvlist.PushBack(f)
} }
@ -236,6 +251,9 @@ func (fm *FrameMgr) combineWindowToRecvBuffer() {
if f.Id == (int32)(id) { if f.Id == (int32)(id) {
left := fm.recvb.Capacity() - fm.recvb.Size() left := fm.recvb.Capacity() - fm.recvb.Size()
if left >= len(f.Data) { if left >= len(f.Data) {
if len(f.Data) == 0 {
fm.remoteclosed = true
}
fm.recvb.Write(f.Data) fm.recvb.Write(f.Data)
fm.recvwin.Remove(e) fm.recvwin.Remove(e)
done = true done = true
@ -261,16 +279,24 @@ func (fm *FrameMgr) combineWindowToRecvBuffer() {
if f.Id != (int32)(id) { if f.Id != (int32)(id) {
reqtmp[id]++ reqtmp[id]++
} else { } else {
reqtmp[id]++
e = e.Next() e = e.Next()
} }
id++ id++
if fm.recvid >= FRAME_MAX_ID { if id >= FRAME_MAX_ID {
fm.recvid = 0 id = 0
} }
} }
for len(reqtmp) < fm.windowsize {
reqtmp[id]++
id++
if id >= FRAME_MAX_ID {
id = 0
}
break
}
f := &Frame{Type: (int32)(Frame_REQ), Resend: false, Sendtime: 0, f := &Frame{Type: (int32)(Frame_REQ), Resend: false, Sendtime: 0,
Id: 0, Id: 0,
Dataid: make([]int32, len(reqtmp))} Dataid: make([]int32, len(reqtmp))}
@ -293,3 +319,14 @@ func (fm *FrameMgr) GetRecvReadLineBuffer() []byte {
func (fm *FrameMgr) SkipRecvBuffer(size int) { func (fm *FrameMgr) SkipRecvBuffer(size int) {
fm.recvb.SkipRead(size) fm.recvb.SkipRead(size)
} }
func (fm *FrameMgr) Close() {
fm.recvlock.Lock()
defer fm.recvlock.Unlock()
fm.close = true
}
func (fm *FrameMgr) IsRemoteClosed() bool {
return fm.remoteclosed
}

View File

@ -88,6 +88,7 @@ type MyMsg struct {
TcpmodeBuffersize int32 `protobuf:"varint,9,opt,name=tcpmode_buffersize,json=tcpmodeBuffersize,proto3" json:"tcpmode_buffersize,omitempty"` TcpmodeBuffersize int32 `protobuf:"varint,9,opt,name=tcpmode_buffersize,json=tcpmodeBuffersize,proto3" json:"tcpmode_buffersize,omitempty"`
TcpmodeMaxwin int32 `protobuf:"varint,10,opt,name=tcpmode_maxwin,json=tcpmodeMaxwin,proto3" json:"tcpmode_maxwin,omitempty"` TcpmodeMaxwin int32 `protobuf:"varint,10,opt,name=tcpmode_maxwin,json=tcpmodeMaxwin,proto3" json:"tcpmode_maxwin,omitempty"`
TcpmodeResendTimems int32 `protobuf:"varint,11,opt,name=tcpmode_resend_timems,json=tcpmodeResendTimems,proto3" json:"tcpmode_resend_timems,omitempty"` TcpmodeResendTimems int32 `protobuf:"varint,11,opt,name=tcpmode_resend_timems,json=tcpmodeResendTimems,proto3" json:"tcpmode_resend_timems,omitempty"`
Timeout int32 `protobuf:"varint,12,opt,name=timeout,proto3" json:"timeout,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -195,6 +196,13 @@ func (m *MyMsg) GetTcpmodeResendTimems() int32 {
return 0 return 0
} }
func (m *MyMsg) GetTimeout() int32 {
if m != nil {
return m.Timeout
}
return 0
}
type Frame struct { type Frame struct {
Type int32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` Type int32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"`
Resend bool `protobuf:"varint,2,opt,name=resend,proto3" json:"resend,omitempty"` Resend bool `protobuf:"varint,2,opt,name=resend,proto3" json:"resend,omitempty"`
@ -284,28 +292,29 @@ func init() {
func init() { proto.RegisterFile("msg.proto", fileDescriptor_c06e4cca6c2cc899) } func init() { proto.RegisterFile("msg.proto", fileDescriptor_c06e4cca6c2cc899) }
var fileDescriptor_c06e4cca6c2cc899 = []byte{ var fileDescriptor_c06e4cca6c2cc899 = []byte{
// 366 bytes of a gzipped FileDescriptorProto // 372 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x51, 0xdd, 0x8a, 0xda, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x51, 0xdd, 0xca, 0xd3, 0x30,
0x18, 0xed, 0x24, 0x99, 0x18, 0x3f, 0xad, 0xc4, 0xe9, 0x0f, 0x43, 0xaf, 0x42, 0xa0, 0x34, 0x37, 0x18, 0x36, 0x6d, 0xd3, 0x75, 0xef, 0x37, 0x3f, 0xba, 0xf8, 0x43, 0xf0, 0xa8, 0x14, 0xc4, 0x9e,
0xed, 0x45, 0xfb, 0x04, 0xd1, 0x5a, 0x91, 0x92, 0x62, 0x07, 0x6f, 0xda, 0x1b, 0x89, 0x66, 0x0c, 0xe8, 0x81, 0x5e, 0x41, 0x37, 0xe7, 0x18, 0x52, 0x99, 0x61, 0x27, 0x7a, 0x32, 0xba, 0x35, 0x2b,
0x43, 0x9b, 0x18, 0x92, 0x91, 0x5d, 0xf7, 0x9d, 0x96, 0x7d, 0x82, 0x7d, 0x9b, 0x7d, 0x90, 0x65, 0x41, 0xd3, 0x96, 0x36, 0x43, 0xe7, 0x3d, 0x89, 0x57, 0xe0, 0xad, 0x89, 0xe4, 0x5d, 0x36, 0x18,
0x3e, 0x47, 0x41, 0xf6, 0x6a, 0xce, 0xf9, 0xce, 0x61, 0xbe, 0x8f, 0x73, 0xa0, 0x5f, 0x75, 0xe5, 0xdf, 0x51, 0x9e, 0x3f, 0x92, 0x87, 0x3c, 0x30, 0xd6, 0x43, 0xfd, 0xa6, 0xeb, 0x5b, 0xd3, 0xa6,
0x97, 0xa6, 0xdd, 0xeb, 0x7d, 0xfc, 0xe4, 0x00, 0xcd, 0x8e, 0x59, 0x57, 0xb2, 0x11, 0x38, 0xaa, 0xff, 0x3c, 0xa0, 0xc5, 0xa9, 0x18, 0x6a, 0x76, 0x0f, 0x9e, 0xaa, 0x38, 0x49, 0x48, 0x36, 0x16,
0xe0, 0x24, 0x22, 0x49, 0x5f, 0x38, 0xaa, 0x60, 0x0c, 0x3c, 0x7d, 0x6c, 0x24, 0x77, 0x22, 0x92, 0x9e, 0xaa, 0x18, 0x83, 0xc0, 0x9c, 0x3a, 0xc9, 0xbd, 0x84, 0x64, 0x54, 0x20, 0x66, 0xcf, 0x21,
0x50, 0x81, 0x98, 0xbd, 0x07, 0x5f, 0xe7, 0x6d, 0x29, 0x35, 0x77, 0xd1, 0x67, 0x99, 0xf1, 0x16, 0x34, 0x65, 0x5f, 0x4b, 0xc3, 0x7d, 0xcc, 0x39, 0x66, 0xb3, 0x55, 0x69, 0x4a, 0x1e, 0x24, 0x24,
0xb9, 0xce, 0xb9, 0x17, 0x91, 0x64, 0x28, 0x10, 0x1b, 0x6f, 0x8b, 0x3b, 0x38, 0x8d, 0x48, 0x32, 0x9b, 0x08, 0xc4, 0x36, 0xdb, 0xe3, 0x1b, 0x9c, 0x26, 0x24, 0x9b, 0x0a, 0xc7, 0xd8, 0x53, 0xa0,
0x16, 0x96, 0xb1, 0xb7, 0x40, 0xab, 0xbc, 0x54, 0x5b, 0xee, 0xe3, 0xf8, 0x44, 0x58, 0x08, 0xee, 0xba, 0xac, 0xd5, 0x9e, 0x87, 0x28, 0x9f, 0x09, 0x8b, 0xc1, 0xff, 0x26, 0x4f, 0x7c, 0x84, 0x9a,
0x3f, 0x79, 0xe4, 0x3d, 0x9c, 0x19, 0xc8, 0x38, 0xf4, 0xf4, 0xb6, 0xa9, 0xf6, 0x85, 0xe4, 0x01, 0x85, 0x8c, 0xc3, 0xc8, 0xec, 0x3b, 0xdd, 0x56, 0x92, 0x47, 0x58, 0xe1, 0x42, 0xd9, 0x6b, 0x60,
0x9e, 0x70, 0xa6, 0xec, 0x33, 0x30, 0x0b, 0xd7, 0x9b, 0xc3, 0x6e, 0x27, 0xdb, 0x4e, 0xdd, 0x49, 0x0e, 0x6e, 0x77, 0xc7, 0xc3, 0x41, 0xf6, 0x83, 0xfa, 0x25, 0xf9, 0x18, 0x43, 0x53, 0xe7, 0xcc,
0xde, 0x47, 0xd3, 0xd8, 0x2a, 0x93, 0x8b, 0xc0, 0x3e, 0xc2, 0xe8, 0x6c, 0xaf, 0xf2, 0xdb, 0x1b, 0xae, 0x06, 0x7b, 0x09, 0xf7, 0x97, 0xb8, 0x2e, 0x7f, 0xfe, 0x50, 0x0d, 0x07, 0x8c, 0x3e, 0x76,
0x55, 0x73, 0x40, 0xeb, 0x6b, 0x3b, 0xcd, 0x70, 0xc8, 0xbe, 0xc2, 0xbb, 0xb3, 0xad, 0x95, 0x9d, 0x6a, 0x81, 0x22, 0x7b, 0x0b, 0xcf, 0x2e, 0xb1, 0x5e, 0x0e, 0xb2, 0xa9, 0xb6, 0x46, 0x69, 0xa9,
0xac, 0x8b, 0xb5, 0x56, 0x95, 0xac, 0x3a, 0x3e, 0x40, 0xf7, 0x1b, 0x2b, 0x0a, 0xd4, 0x56, 0x28, 0x07, 0x7e, 0x87, 0xe9, 0x27, 0xce, 0x14, 0xe8, 0x6d, 0xd0, 0xc2, 0x8e, 0x4a, 0xcb, 0xf6, 0x68,
0xc5, 0x9f, 0xc0, 0x5b, 0xfd, 0x59, 0xce, 0x58, 0x00, 0xde, 0xf7, 0x74, 0x95, 0x86, 0xaf, 0x0c, 0xf8, 0xc4, 0x75, 0x3c, 0xd3, 0xf4, 0x15, 0x04, 0x9b, 0x2f, 0xeb, 0x05, 0x8b, 0x20, 0x78, 0x9f,
0x5a, 0x2e, 0x7e, 0xcd, 0x43, 0xc2, 0x06, 0x40, 0xb3, 0x74, 0xbe, 0x98, 0x86, 0xf7, 0x8f, 0x6e, 0x6f, 0xf2, 0xf8, 0x91, 0x45, 0xeb, 0xd5, 0xa7, 0x65, 0x4c, 0xd8, 0x1d, 0xd0, 0x22, 0x5f, 0xae,
0xfc, 0x40, 0x80, 0xfe, 0x68, 0xf3, 0x4a, 0x5e, 0x62, 0x25, 0xd7, 0xb1, 0x9e, 0x56, 0x62, 0xd8, 0xe6, 0xf1, 0xef, 0xbf, 0x7e, 0xfa, 0x87, 0x00, 0xfd, 0xd0, 0x97, 0x5a, 0x5e, 0x3f, 0x9c, 0xdc,
0x81, 0xb0, 0x8c, 0x7d, 0x80, 0xc0, 0xbc, 0xe6, 0x0e, 0x0c, 0xdc, 0x15, 0x17, 0x6e, 0xeb, 0xf2, 0x7e, 0xf8, 0xb9, 0x0c, 0xce, 0x10, 0x09, 0xc7, 0xd8, 0x0b, 0x88, 0xec, 0x69, 0x5f, 0xc3, 0x29,
0xf0, 0x17, 0x5b, 0x17, 0x56, 0x40, 0xaf, 0x2b, 0x30, 0xaf, 0x2a, 0xb8, 0x1f, 0xb9, 0x09, 0x15, 0x7c, 0x71, 0xe5, 0x6e, 0xc8, 0x00, 0x6f, 0x71, 0x43, 0xe2, 0x38, 0xf4, 0x76, 0x1c, 0x7b, 0xaa,
0x96, 0xc5, 0xf1, 0x8b, 0xb3, 0x7b, 0xe0, 0x8a, 0xd9, 0xef, 0x90, 0x18, 0x90, 0x4e, 0x7f, 0x86, 0x8a, 0x87, 0x89, 0x9f, 0x51, 0xe1, 0x58, 0x9a, 0x3e, 0xa8, 0x3d, 0x02, 0x5f, 0x2c, 0x3e, 0xc7,
0xce, 0x64, 0xf8, 0x17, 0x1a, 0x55, 0x97, 0xfa, 0x50, 0xd7, 0xf2, 0xff, 0xc6, 0xc7, 0xee, 0xbe, 0xc4, 0x82, 0x7c, 0xfe, 0x31, 0xf6, 0x66, 0x93, 0xaf, 0xd0, 0xa9, 0xa6, 0x36, 0xc7, 0xa6, 0x91,
0x3d, 0x07, 0x00, 0x00, 0xff, 0xff, 0xa7, 0xdc, 0xfd, 0xb2, 0x3a, 0x02, 0x00, 0x00, 0xdf, 0x77, 0x21, 0xae, 0xfa, 0xee, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x65, 0x2c, 0xe9,
0x54, 0x02, 0x00, 0x00,
} }

View File

@ -19,6 +19,7 @@ message MyMsg {
int32 tcpmode_buffersize = 9; int32 tcpmode_buffersize = 9;
int32 tcpmode_maxwin = 10; int32 tcpmode_maxwin = 10;
int32 tcpmode_resend_timems = 11; int32 tcpmode_resend_timems = 11;
int32 timeout = 12;
} }
message Frame { message Frame {

View File

@ -65,7 +65,7 @@ func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, ta
continue continue
} }
} }
loggo.Error("sendICMP WriteTo error %s %s", server.String(), err) loggo.Info("sendICMP WriteTo error %s %s", server.String(), err)
} }
break break
} }
@ -83,7 +83,7 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error read icmp message %s", err) loggo.Info("Error read icmp message %s", err)
continue continue
} }
} }
@ -107,11 +107,6 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
continue continue
} }
if my.Data == nil {
loggo.Error("processPacket data nil %s", my.Id)
continue
}
recv <- &Packet{my: my, recv <- &Packet{my: my,
src: srcaddr.(*net.IPAddr), src: srcaddr.(*net.IPAddr),
echoId: echoId, echoSeq: echoSeq} echoId: echoId, echoSeq: echoSeq}

View File

@ -12,13 +12,14 @@ func Test0001(t *testing.T) {
my.Id = "12345" my.Id = "12345"
my.Target = "111:11" my.Target = "111:11"
my.Type = 12 my.Type = 12
my.Data = make([]byte, 3) my.Data = make([]byte, 0)
dst, _ := proto.Marshal(my) dst, _ := proto.Marshal(my)
fmt.Println("dst = ", dst) fmt.Println("dst = ", dst)
my1 := &MyMsg{} my1 := &MyMsg{}
proto.Unmarshal(dst, my1) proto.Unmarshal(dst, my1)
fmt.Println("my1 = ", my1) fmt.Println("my1 = ", my1)
fmt.Println("my1.Data = ", my1.Data)
proto.Unmarshal(dst[0:4], my1) proto.Unmarshal(dst[0:4], my1)
fmt.Println("my1 = ", my1) fmt.Println("my1 = ", my1)

103
server.go
View File

@ -1,6 +1,7 @@
package pingtunnel package pingtunnel
import ( import (
"github.com/esrrhs/go-engine/src/common"
"github.com/esrrhs/go-engine/src/loggo" "github.com/esrrhs/go-engine/src/loggo"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
@ -8,15 +9,13 @@ import (
"time" "time"
) )
func NewServer(timeout int, key int) (*Server, error) { func NewServer(key int) (*Server, error) {
return &Server{ return &Server{
timeout: timeout,
key: key, key: key,
}, nil }, nil
} }
type Server struct { type Server struct {
timeout int
key int key int
conn *icmp.PacketConn conn *icmp.PacketConn
@ -33,6 +32,7 @@ type Server struct {
} }
type ServerConn struct { type ServerConn struct {
timeout int
ipaddrTarget *net.UDPAddr ipaddrTarget *net.UDPAddr
conn *net.UDPConn conn *net.UDPConn
tcpaddrTarget *net.TCPAddr tcpaddrTarget *net.TCPAddr
@ -118,7 +118,7 @@ func (p *Server) processPacket(packet *Packet) {
fm := NewFrameMgr((int)(packet.my.TcpmodeBuffersize), (int)(packet.my.TcpmodeMaxwin), (int)(packet.my.TcpmodeResendTimems)) fm := NewFrameMgr((int)(packet.my.TcpmodeBuffersize), (int)(packet.my.TcpmodeMaxwin), (int)(packet.my.TcpmodeResendTimems))
localConn = &ServerConn{tcpconn: targetConn, tcpaddrTarget: ipaddrTarget, id: id, activeRecvTime: now, activeSendTime: now, close: false, localConn = &ServerConn{timeout: (int)(packet.my.Timeout), tcpconn: targetConn, tcpaddrTarget: ipaddrTarget, id: id, activeRecvTime: now, activeSendTime: now, close: false,
rproto: (int)(packet.my.Rproto), fm: fm, tcpmode: (int)(packet.my.Tcpmode)} rproto: (int)(packet.my.Rproto), fm: fm, tcpmode: (int)(packet.my.Tcpmode)}
p.localConnMap[id] = localConn p.localConnMap[id] = localConn
@ -140,7 +140,7 @@ func (p *Server) processPacket(packet *Packet) {
return return
} }
localConn = &ServerConn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeRecvTime: now, activeSendTime: now, close: false, localConn = &ServerConn{timeout: (int)(packet.my.Timeout), conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeRecvTime: now, activeSendTime: now, close: false,
rproto: (int)(packet.my.Rproto), tcpmode: (int)(packet.my.Tcpmode)} rproto: (int)(packet.my.Rproto), tcpmode: (int)(packet.my.Tcpmode)}
p.localConnMap[id] = localConn p.localConnMap[id] = localConn
@ -166,7 +166,7 @@ func (p *Server) processPacket(packet *Packet) {
} else { } else {
_, err := localConn.conn.Write(packet.my.Data) _, err := localConn.conn.Write(packet.my.Data)
if err != nil { if err != nil {
loggo.Error("WriteToUDP Error %s", err) loggo.Info("WriteToUDP Error %s", err)
localConn.close = true localConn.close = true
return return
} }
@ -183,72 +183,133 @@ func (p *Server) RecvTCP(conn *ServerConn, id string, src *net.IPAddr) {
bytes := make([]byte, 10240) bytes := make([]byte, 10240)
tcpActiveRecvTime := time.Now()
tcpActiveSendTime := time.Now()
for { for {
left := conn.fm.GetSendBufferLeft() now := time.Now()
if left >= len(bytes) {
left := common.MinOfInt(conn.fm.GetSendBufferLeft(), len(bytes))
if left > 0 {
conn.tcpconn.SetReadDeadline(time.Now().Add(time.Millisecond * 100)) conn.tcpconn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
n, err := conn.tcpconn.Read(bytes) n, err := conn.tcpconn.Read(bytes[0:left])
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error read tcp %s %s %s", conn.id, conn.tcpaddrTarget.String(), err) loggo.Info("Error read tcp %s %s %s", conn.id, conn.tcpaddrTarget.String(), err)
conn.fm.Close()
break break
} }
} }
if n > 0 { if n > 0 {
conn.fm.WriteSendBuffer(bytes[:n]) conn.fm.WriteSendBuffer(bytes[:n])
tcpActiveRecvTime = now
} }
} }
conn.fm.Update() conn.fm.Update()
sendlist := conn.fm.getSendList() sendlist := conn.fm.getSendList()
if sendlist.Len() > 0 {
now := time.Now()
conn.activeSendTime = now conn.activeSendTime = now
for e := sendlist.Front(); e != nil; e = e.Next() { for e := sendlist.Front(); e != nil; e = e.Next() {
f := e.Value.(*Frame) f := e.Value.(*Frame)
mb, err := proto.Marshal(f) mb, err := proto.Marshal(f)
if err != nil { if err != nil {
loggo.Error("Error tcp Marshal %s %s %s", conn.id, conn.tcpaddrTarget.String(), err) loggo.Error("Error tcp Marshal %s %s %s", conn.id, conn.tcpaddrTarget.String(), err)
continue continue
} }
sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb, sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb,
conn.rproto, -1, p.key, conn.rproto, -1, p.key,
0, 0, 0, 0) 0, 0, 0, 0)
p.sendPacket++ p.sendPacket++
p.sendPacketSize += (uint64)(len(mb)) p.sendPacketSize += (uint64)(len(mb))
} }
}
if conn.fm.GetRecvBufferSize() > 0 { if conn.fm.GetRecvBufferSize() > 0 {
rr := conn.fm.GetRecvReadLineBuffer() rr := conn.fm.GetRecvReadLineBuffer()
conn.tcpconn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)) conn.tcpconn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100))
n, err := conn.tcpconn.Write(rr) n, err := conn.tcpconn.Write(rr)
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("Error write tcp %s %s %s", conn.id, conn.tcpaddrTarget.String(), err) loggo.Info("Error write tcp %s %s %s", conn.id, conn.tcpaddrTarget.String(), err)
conn.fm.Close()
break break
} }
} }
if n > 0 { if n > 0 {
conn.fm.SkipRecvBuffer(n) conn.fm.SkipRecvBuffer(n)
tcpActiveSendTime = now
} }
} }
diffrecv := now.Sub(conn.activeRecvTime) diffrecv := now.Sub(conn.activeRecvTime)
diffsend := now.Sub(conn.activeSendTime) diffsend := now.Sub(conn.activeSendTime)
if diffrecv > time.Second*(time.Duration(p.timeout)) || diffsend > time.Second*(time.Duration(p.timeout)) { tcpdiffrecv := now.Sub(tcpActiveRecvTime)
tcpdiffsend := now.Sub(tcpActiveSendTime)
if diffrecv > time.Second*(time.Duration(conn.timeout)) || diffsend > time.Second*(time.Duration(conn.timeout)) ||
tcpdiffrecv > time.Second*(time.Duration(conn.timeout)) || tcpdiffsend > time.Second*(time.Duration(conn.timeout)) {
loggo.Info("close inactive conn %s %s", conn.id, conn.tcpaddrTarget.String()) loggo.Info("close inactive conn %s %s", conn.id, conn.tcpaddrTarget.String())
conn.fm.Close()
break
}
if conn.fm.IsRemoteClosed() {
loggo.Info("closed by remote conn %s %s", conn.id, conn.tcpaddrTarget.String())
conn.fm.Close()
break break
} }
} }
startCloseTime := time.Now()
for {
now := time.Now()
conn.fm.Update()
sendlist := conn.fm.getSendList()
for e := sendlist.Front(); e != nil; e = e.Next() {
f := e.Value.(*Frame)
mb, _ := proto.Marshal(f)
sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), mb,
conn.rproto, -1, p.key,
0, 0, 0, 0)
p.sendPacket++
p.sendPacketSize += (uint64)(len(mb))
}
nodatarecv := true
if conn.fm.GetRecvBufferSize() > 0 {
rr := conn.fm.GetRecvReadLineBuffer()
conn.tcpconn.SetWriteDeadline(time.Now().Add(time.Millisecond * 100))
n, _ := conn.tcpconn.Write(rr)
if n > 0 {
conn.fm.SkipRecvBuffer(n)
nodatarecv = false
}
}
diffclose := now.Sub(startCloseTime)
timeout := diffclose > time.Second*(time.Duration(conn.timeout))
remoteclosed := conn.fm.IsRemoteClosed()
if timeout {
loggo.Info("close conn had timeout %s %s", conn.id, conn.tcpaddrTarget.String())
break
}
if remoteclosed && nodatarecv {
loggo.Info("remote conn had closed %s %s", conn.id, conn.tcpaddrTarget.String())
break
}
time.Sleep(time.Millisecond * 100)
}
time.Sleep(time.Second)
loggo.Info("close tcp conn %s %s", conn.id, conn.tcpaddrTarget.String()) loggo.Info("close tcp conn %s %s", conn.id, conn.tcpaddrTarget.String())
p.Close(conn) p.Close(conn)
} }
@ -265,7 +326,7 @@ func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) {
if err != nil { if err != nil {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
if !ok || !nerr.Timeout() { if !ok || !nerr.Timeout() {
loggo.Error("ReadFromUDP Error read udp %s", err) loggo.Info("ReadFromUDP Error read udp %s", err)
conn.close = true conn.close = true
return return
} }
@ -304,7 +365,7 @@ func (p *Server) checkTimeoutConn() {
} }
diffrecv := now.Sub(conn.activeRecvTime) diffrecv := now.Sub(conn.activeRecvTime)
diffsend := now.Sub(conn.activeSendTime) diffsend := now.Sub(conn.activeSendTime)
if diffrecv > time.Second*(time.Duration(p.timeout)) || diffsend > time.Second*(time.Duration(p.timeout)) { if diffrecv > time.Second*(time.Duration(conn.timeout)) || diffsend > time.Second*(time.Duration(conn.timeout)) {
conn.close = true conn.close = true
} }
} }