From 2beaecc53359718fabbfb05f9852ad6d56167a89 Mon Sep 17 00:00:00 2001 From: esrrhs Date: Wed, 19 Dec 2018 14:38:44 +0800 Subject: [PATCH] fix --- client.go | 14 ++++------ cmd/main.go | 14 ++++++---- pingtunnel.go | 76 +++++++++++++++++++++++++++++++++++++++------------ server.go | 9 +++--- 4 files changed, 78 insertions(+), 35 deletions(-) diff --git a/client.go b/client.go index 439d27c..8a14646 100644 --- a/client.go +++ b/client.go @@ -7,7 +7,7 @@ import ( "time" ) -func NewClient(addr string, server string, target string, timeout int, proto int) (*Client, error) { +func NewClient(addr string, server string, target string, timeout int, sproto int, rproto int) (*Client, error) { ipaddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { @@ -26,13 +26,15 @@ func NewClient(addr string, server string, target string, timeout int, proto int addrServer: server, targetAddr: target, timeout: timeout, - proto: proto, + sproto: sproto, + rproto: rproto, }, nil } type Client struct { timeout int - proto int + sproto int + rproto int ipaddr *net.UDPAddr addr string @@ -147,16 +149,12 @@ func (p *Client) Accept() error { } clientConn.activeTime = now - sendICMP(*p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n], p.proto) + sendICMP(*p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n], p.sproto, p.rproto) } } func (p *Client) processPacket(packet *Packet) { - if packet.data == nil { - return - } - fmt.Printf("processPacket %s %s %d\n", packet.id, packet.src.String(), len(packet.data)) clientConn := p.localIdToConnMap[packet.id] diff --git a/cmd/main.go b/cmd/main.go index 007e56f..2d78e0e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,8 +31,11 @@ Usage: -timeout 本地记录连接超时的时间,单位是秒,默认60s The time when the local record connection timed out, in seconds, 60 seconds by default - -proto ping的协议,默认是42 - Ping protocol, the default is 42 + -sproto 客户端发送ping协议的协议,默认是42 + The protocol that the client sends the ping. The default is 42. + + -rproto 客户端接收ping协议的协议,默认是42 + The protocol that the client receives the ping. The default is 42. ` func main() { @@ -42,7 +45,8 @@ func main() { target := flag.String("t", "", "target addr") server := flag.String("s", "", "server addr") timeout := flag.Int("timeout", 60, "conn timeout") - proto := flag.Int("proto", 2, "ping proto") + sproto := flag.Int("sproto", 42, "send ping proto") + rproto := flag.Int("rproto", 42, "recv ping proto") flag.Usage = func() { fmt.Printf(usage) } @@ -57,7 +61,7 @@ func main() { fmt.Println("start...") if *t == "server" { - s, err := pingtunnel.NewServer(*timeout, *proto) + s, err := pingtunnel.NewServer(*timeout) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) return @@ -72,7 +76,7 @@ func main() { fmt.Printf("server %s\n", *server) fmt.Printf("target %s\n", *target) - c, err := pingtunnel.NewClient(*listen, *server, *target, *timeout, *proto) + c, err := pingtunnel.NewClient(*listen, *server, *target, *timeout, *sproto, *rproto) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) return diff --git a/pingtunnel.go b/pingtunnel.go index f4f5061..664bcb7 100644 --- a/pingtunnel.go +++ b/pingtunnel.go @@ -21,10 +21,12 @@ const ( // An Echo represents an ICMP echo request or reply message body. type MyMsg struct { - TYPE uint32 - ID string - TARGET string - Data []byte + TYPE uint32 + ID string + TARGET string + Data []byte + RPROTO uint16 + ENDTYPE uint32 } // Len implements the Len method of MessageBody interface. @@ -32,13 +34,17 @@ func (p *MyMsg) Len(proto int) int { if p == nil { return 0 } - return 4 + p.LenString(p.ID) + p.LenString(p.TARGET) + len(p.Data) + return 4 + p.LenString(p.ID) + p.LenString(p.TARGET) + p.LenData(p.Data) + 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) { @@ -52,7 +58,12 @@ func (p *MyMsg) Marshal(proto int) ([]byte, error) { target := p.MarshalString(p.TARGET) copy(b[4+p.LenString(p.ID):], target) - copy(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):], p.Data) + 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.PutUint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+2:], uint32(p.ENDTYPE)) return b, nil } @@ -64,6 +75,13 @@ func (p *MyMsg) MarshalString(s string) []byte { 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() { @@ -76,30 +94,48 @@ func (p *MyMsg) Unmarshal(b []byte) error { p.TARGET = p.UnmarshalString(b[4+p.LenString(p.ID):]) - p.Data = make([]byte, len(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):])) - copy(p.Data, b[4+p.LenString(p.ID)+p.LenString(p.TARGET):]) + 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.ENDTYPE = binary.BigEndian.Uint32(b[4+p.LenString(p.ID)+p.LenString(p.TARGET)+p.LenData(p.Data)+2:]) 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 sendICMP(conn icmp.PacketConn, server *net.IPAddr, target string, connId string, msgType uint32, data []byte, proto int) { +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(conn icmp.PacketConn, server *net.IPAddr, target string, connId string, msgType uint32, data []byte, sproto int, rproto int) { m := &MyMsg{ - ID: connId, - TYPE: msgType, - TARGET: target, - Data: data, + ID: connId, + TYPE: msgType, + TARGET: target, + Data: data, + RPROTO: (uint16)(rproto), + ENDTYPE: msgType, } msg := &icmp.Message{ - Type: (ipv4.ICMPType)(proto), + Type: (ipv4.ICMPType)(sproto), Code: 0, Body: m, } @@ -148,12 +184,17 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) { } my.Unmarshal(bytes[4:n]) - if my.TYPE != (uint32)(DATA) { - fmt.Printf("processPacket diff type %d \n", my.TYPE) + if my.TYPE != (uint32)(DATA) || my.ENDTYPE != (uint32)(DATA) { + fmt.Printf("processPacket diff type %s %d %d \n", my.ID, my.TYPE, my.ENDTYPE) continue } - recv <- &Packet{data: my.Data, id: my.ID, target: my.TARGET, src: srcaddr.(*net.IPAddr)} + if my.Data == nil { + fmt.Printf("processPacket data nil %s\n", my.ID) + return + } + + recv <- &Packet{data: my.Data, id: my.ID, target: my.TARGET, src: srcaddr.(*net.IPAddr), rproto: (int)(my.RPROTO)} } } @@ -162,6 +203,7 @@ type Packet struct { id string target string src *net.IPAddr + rproto int } func UniqueId() string { diff --git a/server.go b/server.go index d00e2fb..98474b9 100644 --- a/server.go +++ b/server.go @@ -7,16 +7,14 @@ import ( "time" ) -func NewServer(timeout int, proto int) (*Server, error) { +func NewServer(timeout int) (*Server, error) { return &Server{ timeout: timeout, - proto: proto, }, nil } type Server struct { timeout int - proto int conn *icmp.PacketConn @@ -29,6 +27,7 @@ type ServerConn struct { id string activeTime time.Time close bool + rproto int } func (p *Server) Run() { @@ -80,7 +79,7 @@ func (p *Server) processPacket(packet *Packet) { fmt.Printf("Error listening for udp packets: %s\n", err.Error()) return } - udpConn = &ServerConn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeTime: now, close: false} + udpConn = &ServerConn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeTime: now, close: false, rproto: packet.rproto} p.localConnMap[id] = udpConn go p.Recv(udpConn, id, packet.src) } @@ -120,7 +119,7 @@ func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) { now := time.Now() conn.activeTime = now - sendICMP(*p.conn, src, "", id, (uint32)(DATA), bytes[:n], p.proto) + sendICMP(*p.conn, src, "", id, (uint32)(DATA), bytes[:n], conn.rproto, 0) } }