diff --git a/client.go b/client.go index d397d1c..8915d39 100644 --- a/client.go +++ b/client.go @@ -2,6 +2,7 @@ package pingtunnel import ( "github.com/esrrhs/go-engine/src/loggo" + "github.com/golang/protobuf/proto" "golang.org/x/net/icmp" "math" "math/rand" @@ -9,7 +10,12 @@ import ( "time" ) -func NewClient(addr string, server string, target string, timeout int, sproto int, rproto int, catch int, key int, +const ( + SEND_PROTO int = 8 + RECV_PROTO int = 0 +) + +func NewClient(addr string, server string, target string, timeout int, catch int, key int, tcpmode int) (*Client, error) { var ipaddr *net.UDPAddr @@ -43,8 +49,6 @@ func NewClient(addr string, server string, target string, timeout int, sproto in addrServer: server, targetAddr: target, timeout: timeout, - sproto: sproto, - rproto: rproto, catch: catch, key: key, tcpmode: tcpmode, @@ -258,7 +262,7 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn) { for e := sendlist.Front(); e != nil; e = e.Next() { f := e.Value.(Frame) - mb, err := f.Marshal(0) + mb, err := proto.Marshal(&f) if err != nil { loggo.Error("Error tcp Marshal %s %s %s", uuid, tcpsrcaddr.String(), err) break @@ -267,10 +271,11 @@ func (p *Client) AcceptTcpConn(conn *net.TCPConn) { p.sequence++ p.sendPacket++ - p.sendPacketSize += (uint64)(f.size) + p.sendPacketSize += (uint64)(len(mb)) - sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), mb, - p.sproto, p.rproto, p.catch, p.key, p.tcpmode) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), mb, + SEND_PROTO, RECV_PROTO, p.catch, p.key, + p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems) } } @@ -311,8 +316,9 @@ func (p *Client) Accept() error { } clientConn.activeTime = now - sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n], - p.sproto, p.rproto, p.catch, p.key, p.tcpmode) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(MyMsg_DATA), bytes[:n], + SEND_PROTO, RECV_PROTO, p.catch, p.key, + p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems) p.sequence++ @@ -323,11 +329,11 @@ func (p *Client) Accept() error { func (p *Client) processPacket(packet *Packet) { - if packet.rproto >= 0 { + if packet.my.Rproto >= 0 { return } - if packet.key != p.key { + if packet.my.Key != (int32)(p.key) { return } @@ -335,19 +341,19 @@ func (p *Client) processPacket(packet *Packet) { return } - if packet.msgType == PING { + if packet.my.Type == (int32)(MyMsg_PING) { t := time.Time{} - t.UnmarshalBinary(packet.data) + t.UnmarshalBinary(packet.my.Data) d := time.Now().Sub(t) loggo.Info("pong from %s %s", packet.src.String(), d.String()) return } - //loggo.Debug("processPacket %s %s %d", packet.id, packet.src.String(), len(packet.data)) + loggo.Debug("processPacket %s %s %d", packet.my.Id, packet.src.String(), len(packet.my.Data)) - clientConn := p.localIdToConnMap[packet.id] + clientConn := p.localIdToConnMap[packet.my.Id] if clientConn == nil { - //loggo.Debug("processPacket no conn %s ", packet.id) + loggo.Debug("processPacket no conn %s ", packet.my.Id) return } @@ -356,11 +362,11 @@ func (p *Client) processPacket(packet *Packet) { now := time.Now() clientConn.activeTime = now - if packet.msgType == CATCH { + if packet.my.Type == (int32)(MyMsg_CATCH) { p.recvCatchPacket++ } - _, err := p.listenConn.WriteToUDP(packet.data, addr) + _, err := p.listenConn.WriteToUDP(packet.my.Data, addr) if err != nil { loggo.Error("WriteToUDP Error read udp %s", err) clientConn.close = true @@ -368,7 +374,7 @@ func (p *Client) processPacket(packet *Packet) { } p.recvPacket++ - p.recvPacketSize += (uint64)(len(packet.data)) + p.recvPacketSize += (uint64)(len(packet.my.Data)) } func (p *Client) Close(clientConn *ClientConn) { @@ -404,8 +410,9 @@ func (p *Client) ping() { if p.sendPacket == 0 { now := time.Now() b, _ := now.MarshalBinary() - sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(PING), b, - p.sproto, p.rproto, p.catch, p.key, p.tcpmode) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(MyMsg_PING), b, + SEND_PROTO, RECV_PROTO, p.catch, p.key, + p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems) loggo.Info("ping %s %s %d %d %d %d", p.addrServer, now.String(), p.sproto, p.rproto, p.id, p.sequence) p.sequence++ } @@ -425,8 +432,9 @@ func (p *Client) showNet() { func (p *Client) sendCatch() { if p.catch > 0 { for _, conn := range p.localIdToConnMap { - sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, conn.id, (uint32)(CATCH), make([]byte, 0), - p.sproto, p.rproto, p.catch, p.key, p.tcpmode) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, conn.id, (uint32)(MyMsg_CATCH), make([]byte, 0), + SEND_PROTO, RECV_PROTO, p.catch, p.key, + p.tcpmode, p.tcpmode_buffersize, p.tcpmode_maxwin, p.tcpmode_resend_timems) p.sequence++ p.sendCatchPacket++ } diff --git a/framemgr.go b/framemgr.go index 2bb67d4..f5fd26d 100644 --- a/framemgr.go +++ b/framemgr.go @@ -60,10 +60,10 @@ func (fm *FrameMgr) cutSendBufferToWindow() { } for fm.sendb.Size() > FRAME_MAX_SIZE && fm.win.Len() < fm.windowsize { - f := Frame{resend: false, sendtime: 0, - id: fm.sendid, size: FRAME_MAX_SIZE, - data: make([]byte, FRAME_MAX_SIZE)} - fm.sendb.Read(f.data) + f := Frame{Resend: false, Sendtime: 0, + Id: (int32)(fm.sendid), + Data: make([]byte, FRAME_MAX_SIZE)} + fm.sendb.Read(f.Data) fm.sendid++ if fm.sendid > FRAME_MAX_ID { @@ -74,10 +74,10 @@ func (fm *FrameMgr) cutSendBufferToWindow() { } if sendall && fm.sendb.Size() > 0 && fm.win.Len() < fm.windowsize { - f := Frame{resend: false, sendtime: 0, - id: fm.sendid, size: fm.sendb.Size(), - data: make([]byte, fm.sendb.Size())} - fm.sendb.Read(f.data) + f := Frame{Resend: false, Sendtime: 0, + Id: (int32)(fm.sendid), + Data: make([]byte, fm.sendb.Size())} + fm.sendb.Read(f.Data) fm.sendid++ if fm.sendid > FRAME_MAX_ID { @@ -95,8 +95,8 @@ func (fm *FrameMgr) calSendList() { for e := fm.win.Front(); e != nil; e = e.Next() { f := e.Value.(Frame) - if f.resend || cur-f.sendtime > int64(fm.resend_timems*1000) { - f.sendtime = cur + if f.Resend || cur-f.Sendtime > int64(fm.resend_timems*1000) { + f.Sendtime = cur fm.sendlist.PushBack(&f) } } diff --git a/pingtunnel.go b/pingtunnel.go index 13ccd9e..84bb222 100644 --- a/pingtunnel.go +++ b/pingtunnel.go @@ -7,6 +7,7 @@ import ( "encoding/binary" "encoding/hex" "github.com/esrrhs/go-engine/src/loggo" + "github.com/golang/protobuf/proto" "golang.org/x/net/icmp" "golang.org/x/net/ipv4" "io" @@ -15,147 +16,29 @@ import ( "time" ) -const ( - DATA uint32 = 0x01010101 - PING uint32 = 0x02020202 - CATCH uint32 = 0x03030303 -) - -type MyMsg struct { - TYPE uint32 - ID string - TARGET string - Data []byte - RPROTO uint16 - CATCH uint16 - KEY uint32 - TCPMODE uint16 - ENDTYPE uint32 -} - -// Len implements the Len method of MessageBody interface. -func (p *MyMsg) Len(proto int) int { - if p == nil { - return 0 - } - return 4 + p.LenString(p.ID) + p.LenString(p.TARGET) + p.LenData(p.Data) + 2 + 2 + 4 + 2 + 4 -} - -func (p *MyMsg) LenString(s string) int { - return 2 + len(s) -} - -func (p *MyMsg) LenData(data []byte) int { - return 2 + len(data) -} - -// Marshal implements the Marshal method of MessageBody interface. -func (p *MyMsg) Marshal(proto int) ([]byte, error) { - - b := make([]byte, p.Len(proto)) - - binary.BigEndian.PutUint32(b[:4], uint32(p.TYPE)) - - id := p.MarshalString(p.ID) - copy(b[4:], id) - - target := p.MarshalString(p.TARGET) - copy(b[4+p.LenString(p.ID):], target) - - data := p.MarshalData(p.Data) - copy(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):], data) - - binary.BigEndian.PutUint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data):], uint16(p.RPROTO)) - - binary.BigEndian.PutUint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+2:], uint16(p.CATCH)) - - binary.BigEndian.PutUint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+4:], uint32(p.KEY)) - - binary.BigEndian.PutUint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+8:], uint16(p.TCPMODE)) - - binary.BigEndian.PutUint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+10:], uint32(p.ENDTYPE)) - - return b, nil -} - -func (p *MyMsg) MarshalString(s string) []byte { - b := make([]byte, p.LenString(s)) - binary.BigEndian.PutUint16(b[:2], uint16(len(s))) - copy(b[2:], []byte(s)) - return b -} - -func (p *MyMsg) MarshalData(data []byte) []byte { - b := make([]byte, p.LenData(data)) - binary.BigEndian.PutUint16(b[:2], uint16(len(data))) - copy(b[2:], []byte(data)) - return b -} - -// Marshal implements the Marshal method of MessageBody interface. -func (p *MyMsg) Unmarshal(b []byte) error { - defer func() { - recover() - }() - - p.TYPE = binary.BigEndian.Uint32(b[:4]) - - p.ID = p.UnmarshalString(b[4:]) - - p.TARGET = p.UnmarshalString(b[4+p.LenString(p.ID):]) - - p.Data = p.UnmarshalData(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):]) - - p.RPROTO = binary.BigEndian.Uint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data):]) - - p.CATCH = binary.BigEndian.Uint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+2:]) - - p.KEY = binary.BigEndian.Uint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+4:]) - - p.TCPMODE = binary.BigEndian.Uint16(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+8:]) - - p.ENDTYPE = binary.BigEndian.Uint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+10:]) - - return nil -} - -func (p *MyMsg) UnmarshalString(b []byte) string { - len := binary.BigEndian.Uint16(b[:2]) - if len > 32 || len < 0 { - panic(nil) - } - data := make([]byte, len) - copy(data, b[2:]) - return string(data) -} - -func (p *MyMsg) UnmarshalData(b []byte) []byte { - len := binary.BigEndian.Uint16(b[:2]) - if len > 2048 || len < 0 { - panic(nil) - } - data := make([]byte, len) - copy(data, b[2:]) - return data -} - func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, target string, connId string, msgType uint32, data []byte, sproto int, rproto int, catch int, key int, - tcpmode int) { + tcpmode int, tcpmode_buffer_size int, tcpmode_maxwin int, tcpmode_resend_time int) { m := &MyMsg{ - ID: connId, - TYPE: msgType, - TARGET: target, - Data: data, - RPROTO: (uint16)(rproto), - CATCH: (uint16)(catch), - KEY: (uint32)(key), - TCPMODE: (uint16)(tcpmode), - ENDTYPE: END, + Id: connId, + Type: (int32)(msgType), + Target: target, + Data: data, + Rproto: (int32)(rproto), + Catch: (int32)(catch), + Key: (int32)(key), + Tcpmode: (int32)(tcpmode), + TcpmodeBuffersize: (int32)(tcpmode_buffer_size), + TcpmodeMaxwin: (int32)(tcpmode_maxwin), + TcpmodeResendTimems: (int32)(tcpmode_resend_time), } - mb, err := m.Marshal(0) + mb, err := proto.Marshal(m) + if err != nil { + loggo.Error("sendICMP Marshal MyMsg error %s %s", server.String(), err) + return + } body := &icmp.Echo{ ID: id, @@ -213,38 +96,28 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) { echoSeq := int(binary.BigEndian.Uint16(bytes[6:8])) my := &MyMsg{} - my.Unmarshal(bytes[8:n]) - - if (my.TYPE != (uint32)(DATA) && my.TYPE != (uint32)(PING) && my.TYPE != (uint32)(CATCH)) || - my.ENDTYPE != (uint32)(END) { - loggo.Info("processPacket diff type %s %d %d ", my.ID, my.TYPE, my.ENDTYPE) + err = proto.Unmarshal(bytes[8:n], my) + if err != nil { + loggo.Debug("Unmarshal MyMsg error: %s", err) continue } if my.Data == nil { - loggo.Info("processPacket data nil %s", my.ID) + loggo.Info("processPacket data nil %s", my.Id) return } - recv <- &Packet{msgType: my.TYPE, data: my.Data, id: my.ID, target: my.TARGET, - src: srcaddr.(*net.IPAddr), rproto: (int)((int16)(my.RPROTO)), - echoId: echoId, echoSeq: echoSeq, catch: (int)((int16)(my.CATCH)), - key: (int)(my.KEY), tcpmode: (int)((int16)(my.TCPMODE))} + recv <- &Packet{my: my, + src: srcaddr.(*net.IPAddr), + echoId: echoId, echoSeq: echoSeq} } } type Packet struct { - msgType uint32 - data []byte - id string - target string + my *MyMsg src *net.IPAddr - rproto int echoId int echoSeq int - catch int - key int - tcpmode int } func UniqueId() string { @@ -279,36 +152,3 @@ const ( FRAME_TYPE_REQ int = 0x0202 FRAME_TYPE_ACK int = 0x0303 ) - -type Frame struct { - ty int - resend bool - sendtime int64 - id int - size int - data []byte - dataid []int -} - -// Marshal implements the Marshal method of MessageBody interface. -func (p *Frame) Marshal(proto int) ([]byte, error) { - - b := make([]byte, p.Len(proto)) - - binary.BigEndian.PutUint16(b[:2], uint16(p.ty)) - - datalen := len(p.data) - binary.BigEndian.PutUint16(b[2:4], uint16(datalen)) - - // TODO - - return b, nil -} - -// Len implements the Len method of MessageBody interface. -func (p *Frame) Len(proto int) int { - if p == nil { - return 0 - } - return 4 + 2 + 4 + 4 // TODO -} diff --git a/pingtunnel_test.go b/pingtunnel_test.go index 98788c5..23891a3 100644 --- a/pingtunnel_test.go +++ b/pingtunnel_test.go @@ -2,27 +2,24 @@ package pingtunnel import ( "fmt" - "github.com/esrrhs/pingtunnel" + "github.com/golang/protobuf/proto" "testing" ) func Test0001(test *testing.T) { - my := &pingtunnel.MyMsg{ - } - my.ID = "12345" - my.TARGET = "111:11" - my.TYPE = 12 + my := &MyMsg{} + my.Id = "12345" + my.Target = "111:11" + my.Type = 12 my.Data = make([]byte, 3) - dst,_ := my.Marshal(0) + dst, _ := proto.Marshal(my) fmt.Println("dst = ", dst) - - my1 := &pingtunnel.MyMsg{ - } - my1.Unmarshal(dst) + my1 := &MyMsg{} + proto.Unmarshal(dst, my1) fmt.Println("my1 = ", my1) - my1.Unmarshal(dst[0:4]) + proto.Unmarshal(dst[0:4], my1) fmt.Println("my1 = ", my1) } diff --git a/server.go b/server.go index 5e8cb4c..e317dc6 100644 --- a/server.go +++ b/server.go @@ -77,33 +77,34 @@ func (p *Server) Run() { func (p *Server) processPacket(packet *Packet) { - if packet.key != p.key { + if packet.my.Key != (int32)(p.key) { return } p.echoId = packet.echoId p.echoSeq = packet.echoSeq - if packet.msgType == PING { + if packet.my.Type == (int32)(MyMsg_PING) { t := time.Time{} - t.UnmarshalBinary(packet.data) - loggo.Info("ping from %s %s %d %d %d", packet.src.String(), t.String(), packet.rproto, packet.echoId, packet.echoSeq) - sendICMP(packet.echoId, packet.echoSeq, *p.conn, packet.src, "", "", (uint32)(PING), packet.data, - packet.rproto, -1, 0, p.key, packet.tcpmode) + t.UnmarshalBinary(packet.my.Data) + loggo.Info("ping from %s %s %d %d %d", packet.src.String(), t.String(), packet.my.Rproto, packet.echoId, packet.echoSeq) + sendICMP(packet.echoId, packet.echoSeq, *p.conn, packet.src, "", "", (uint32)(MyMsg_PING), packet.my.Data, + (int)(packet.my.Rproto), -1, 0, p.key, + 0, 0, 0, 0) return } - loggo.Debug("processPacket %s %s %d", packet.id, packet.src.String(), len(packet.data)) + loggo.Debug("processPacket %s %s %d", packet.my.Id, packet.src.String(), len(packet.my.Data)) now := time.Now() - id := packet.id + id := packet.my.Id localConn := p.localConnMap[id] if localConn == nil { - if packet.tcpmode > 0 { + if packet.my.Tcpmode > 0 { - addr := packet.target + addr := packet.my.Target ipaddrTarget, err := net.ResolveTCPAddr("tcp", addr) if err != nil { loggo.Error("Error ResolveUDPAddr for tcp addr: %s %s", addr, err.Error()) @@ -116,10 +117,10 @@ func (p *Server) processPacket(packet *Packet) { return } - catchQueue := make(chan *CatchMsg, packet.catch) + catchQueue := make(chan *CatchMsg, packet.my.Catch) localConn = &ServerConn{tcpconn: targetConn, tcpaddrTarget: ipaddrTarget, id: id, activeTime: now, close: false, - rproto: packet.rproto, catchQueue: catchQueue} + rproto: (int)(packet.my.Rproto), catchQueue: catchQueue} p.localConnMap[id] = localConn @@ -127,7 +128,7 @@ func (p *Server) processPacket(packet *Packet) { } else { - addr := packet.target + addr := packet.my.Target ipaddrTarget, err := net.ResolveUDPAddr("udp", addr) if err != nil { loggo.Error("Error ResolveUDPAddr for udp addr: %s %s", addr, err.Error()) @@ -140,10 +141,10 @@ func (p *Server) processPacket(packet *Packet) { return } - catchQueue := make(chan *CatchMsg, packet.catch) + catchQueue := make(chan *CatchMsg, packet.my.Catch) localConn = &ServerConn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeTime: now, close: false, - rproto: packet.rproto, catchQueue: catchQueue} + rproto: (int)(packet.my.Rproto), catchQueue: catchQueue} p.localConnMap[id] = localConn @@ -152,13 +153,14 @@ func (p *Server) processPacket(packet *Packet) { } localConn.activeTime = now - localConn.catch = packet.catch + localConn.catch = (int)(packet.my.Catch) - if packet.msgType == CATCH { + if packet.my.Type == (int32)(MyMsg_CATCH) { select { case re := <-localConn.catchQueue: - sendICMP(packet.echoId, packet.echoSeq, *p.conn, re.src, "", re.id, (uint32)(CATCH), re.data, - re.conn.rproto, -1, 0, p.key, packet.tcpmode) + sendICMP(packet.echoId, packet.echoSeq, *p.conn, re.src, "", re.id, (uint32)(MyMsg_CATCH), re.data, + re.conn.rproto, -1, 0, p.key, + 0, 0, 0, 0) p.sendCatchPacket++ case <-time.After(time.Duration(1) * time.Millisecond): } @@ -166,9 +168,9 @@ func (p *Server) processPacket(packet *Packet) { return } - if packet.msgType == DATA { + if packet.my.Type == (int32)(MyMsg_DATA) { - _, err := localConn.conn.Write(packet.data) + _, err := localConn.conn.Write(packet.my.Data) if err != nil { loggo.Error("WriteToUDP Error %s", err) localConn.close = true @@ -176,7 +178,7 @@ func (p *Server) processPacket(packet *Packet) { } p.recvPacket++ - p.recvPacketSize += (uint64)(len(packet.data)) + p.recvPacketSize += (uint64)(len(packet.my.Data)) } } @@ -211,8 +213,9 @@ func (p *Server) RecvTCP(conn *ServerConn, id string, src *net.IPAddr) { case <-time.After(time.Duration(10) * time.Millisecond): } } else { - sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(DATA), bytes[:n], - conn.rproto, -1, 0, p.key, 0) + sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), bytes[:n], + conn.rproto, -1, 0, p.key, + 0, 0, 0, 0) } p.sendPacket++ @@ -251,8 +254,9 @@ func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) { case <-time.After(time.Duration(10) * time.Millisecond): } } else { - sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(DATA), bytes[:n], - conn.rproto, -1, 0, p.key, 0) + sendICMP(p.echoId, p.echoSeq, *p.conn, src, "", id, (uint32)(MyMsg_DATA), bytes[:n], + conn.rproto, -1, 0, p.key, + 0, 0, 0, 0) } p.sendPacket++