This commit is contained in:
esrrhs 2018-12-19 14:38:44 +08:00
parent 743b82dda4
commit 2beaecc533
4 changed files with 78 additions and 35 deletions

View File

@ -7,7 +7,7 @@ import (
"time" "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) ipaddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil { if err != nil {
@ -26,13 +26,15 @@ func NewClient(addr string, server string, target string, timeout int, proto int
addrServer: server, addrServer: server,
targetAddr: target, targetAddr: target,
timeout: timeout, timeout: timeout,
proto: proto, sproto: sproto,
rproto: rproto,
}, nil }, nil
} }
type Client struct { type Client struct {
timeout int timeout int
proto int sproto int
rproto int
ipaddr *net.UDPAddr ipaddr *net.UDPAddr
addr string addr string
@ -147,16 +149,12 @@ func (p *Client) Accept() error {
} }
clientConn.activeTime = now 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) { 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)) fmt.Printf("processPacket %s %s %d\n", packet.id, packet.src.String(), len(packet.data))
clientConn := p.localIdToConnMap[packet.id] clientConn := p.localIdToConnMap[packet.id]

View File

@ -31,8 +31,11 @@ Usage:
-timeout 本地记录连接超时的时间单位是秒默认60s -timeout 本地记录连接超时的时间单位是秒默认60s
The time when the local record connection timed out, in seconds, 60 seconds by default The time when the local record connection timed out, in seconds, 60 seconds by default
-proto ping的协议默认是42 -sproto 客户端发送ping协议的协议默认是42
Ping protocol, the default is 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() { func main() {
@ -42,7 +45,8 @@ func main() {
target := flag.String("t", "", "target addr") target := flag.String("t", "", "target addr")
server := flag.String("s", "", "server addr") server := flag.String("s", "", "server addr")
timeout := flag.Int("timeout", 60, "conn timeout") 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() { flag.Usage = func() {
fmt.Printf(usage) fmt.Printf(usage)
} }
@ -57,7 +61,7 @@ func main() {
fmt.Println("start...") fmt.Println("start...")
if *t == "server" { if *t == "server" {
s, err := pingtunnel.NewServer(*timeout, *proto) s, err := pingtunnel.NewServer(*timeout)
if err != nil { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
return return
@ -72,7 +76,7 @@ func main() {
fmt.Printf("server %s\n", *server) fmt.Printf("server %s\n", *server)
fmt.Printf("target %s\n", *target) 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 { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
return return

View File

@ -21,10 +21,12 @@ const (
// An Echo represents an ICMP echo request or reply message body. // An Echo represents an ICMP echo request or reply message body.
type MyMsg struct { type MyMsg struct {
TYPE uint32 TYPE uint32
ID string ID string
TARGET string TARGET string
Data []byte Data []byte
RPROTO uint16
ENDTYPE uint32
} }
// Len implements the Len method of MessageBody interface. // Len implements the Len method of MessageBody interface.
@ -32,13 +34,17 @@ func (p *MyMsg) Len(proto int) int {
if p == nil { if p == nil {
return 0 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 { func (p *MyMsg) LenString(s string) int {
return 2 + len(s) return 2 + len(s)
} }
func (p *MyMsg) LenData(data []byte) int {
return 2 + len(data)
}
// Marshal implements the Marshal method of MessageBody interface. // Marshal implements the Marshal method of MessageBody interface.
func (p *MyMsg) Marshal(proto int) ([]byte, error) { 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) target := p.MarshalString(p.TARGET)
copy(b[4+p.LenString(p.ID):], 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 return b, nil
} }
@ -64,6 +75,13 @@ func (p *MyMsg) MarshalString(s string) []byte {
return b 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. // Marshal implements the Marshal method of MessageBody interface.
func (p *MyMsg) Unmarshal(b []byte) error { func (p *MyMsg) Unmarshal(b []byte) error {
defer func() { defer func() {
@ -76,30 +94,48 @@ func (p *MyMsg) Unmarshal(b []byte) error {
p.TARGET = p.UnmarshalString(b[4+p.LenString(p.ID):]) 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):])) p.Data = p.UnmarshalData(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):])
copy(p.Data, 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 return nil
} }
func (p *MyMsg) UnmarshalString(b []byte) string { func (p *MyMsg) UnmarshalString(b []byte) string {
len := binary.BigEndian.Uint16(b[:2]) len := binary.BigEndian.Uint16(b[:2])
if len > 32 || len < 0 {
panic(nil)
}
data := make([]byte, len) data := make([]byte, len)
copy(data, b[2:]) copy(data, b[2:])
return string(data) 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{ m := &MyMsg{
ID: connId, ID: connId,
TYPE: msgType, TYPE: msgType,
TARGET: target, TARGET: target,
Data: data, Data: data,
RPROTO: (uint16)(rproto),
ENDTYPE: msgType,
} }
msg := &icmp.Message{ msg := &icmp.Message{
Type: (ipv4.ICMPType)(proto), Type: (ipv4.ICMPType)(sproto),
Code: 0, Code: 0,
Body: m, Body: m,
} }
@ -148,12 +184,17 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
} }
my.Unmarshal(bytes[4:n]) my.Unmarshal(bytes[4:n])
if my.TYPE != (uint32)(DATA) { if my.TYPE != (uint32)(DATA) || my.ENDTYPE != (uint32)(DATA) {
fmt.Printf("processPacket diff type %d \n", my.TYPE) fmt.Printf("processPacket diff type %s %d %d \n", my.ID, my.TYPE, my.ENDTYPE)
continue 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 id string
target string target string
src *net.IPAddr src *net.IPAddr
rproto int
} }
func UniqueId() string { func UniqueId() string {

View File

@ -7,16 +7,14 @@ import (
"time" "time"
) )
func NewServer(timeout int, proto int) (*Server, error) { func NewServer(timeout int) (*Server, error) {
return &Server{ return &Server{
timeout: timeout, timeout: timeout,
proto: proto,
}, nil }, nil
} }
type Server struct { type Server struct {
timeout int timeout int
proto int
conn *icmp.PacketConn conn *icmp.PacketConn
@ -29,6 +27,7 @@ type ServerConn struct {
id string id string
activeTime time.Time activeTime time.Time
close bool close bool
rproto int
} }
func (p *Server) Run() { 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()) fmt.Printf("Error listening for udp packets: %s\n", err.Error())
return 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 p.localConnMap[id] = udpConn
go p.Recv(udpConn, id, packet.src) 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() now := time.Now()
conn.activeTime = 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)
} }
} }