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"
)
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]

View File

@ -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

View File

@ -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 {

View File

@ -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)
}
}