This commit is contained in:
esrrhs 2018-12-18 11:39:16 +08:00
parent a8910116d2
commit 429083487b
4 changed files with 87 additions and 73 deletions

View File

@ -9,9 +9,9 @@ import (
var usage = ` var usage = `
Usage: Usage:
pingtunnel -type server -t TARGET_IP:4455 pingtunnel -type server
pingtunnel -type client -l LOCAL_IP:4455 -t SERVER_IP pingtunnel -type client -l LOCAL_IP:4455 -s SERVER_IP -t 4455
` `
@ -20,7 +20,8 @@ func main() {
t := flag.String("type", "client", "client or server") t := flag.String("type", "client", "client or server")
listen := flag.String("l", ":4455", "listen addr") listen := flag.String("l", ":4455", "listen addr")
target := flag.String("t", ":443", "target addr") target := flag.Int("t", 4455, "target port")
server := flag.String("s", "127.0.0.1", "server addr")
flag.Usage = func() { flag.Usage = func() {
fmt.Printf(usage) fmt.Printf(usage)
} }
@ -34,24 +35,26 @@ func main() {
fmt.Printf("type %s\n", *t) fmt.Printf("type %s\n", *t)
fmt.Printf("listen %s\n", *listen) fmt.Printf("listen %s\n", *listen)
fmt.Printf("target %s\n", *target) fmt.Printf("server %s\n", *server)
fmt.Printf("target port %d\n", *target)
if *t == "server" { if *t == "server" {
s, err := pingtunnel.NewServer(*target) s, err := pingtunnel.NewServer()
if err != nil { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
return return
} }
fmt.Printf("Server Target %s (%s):\n", s.TargetAddr(), s.TargetIPAddr()) fmt.Printf("Server start\n")
s.Run() s.Run()
} }
if *t == "client" { if *t == "client" {
c, err := pingtunnel.NewClient(*listen, *target) c, err := pingtunnel.NewClient(*listen, *server, *target)
if err != nil { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
return return
} }
fmt.Printf("Client Listen %s (%s) Target %s (%s):\n", c.Addr(), c.IPAddr(), c.TargetAddr(), c.TargetIPAddr()) fmt.Printf("Client Listen %s (%s) Server %s (%s) TargetPort %d:\n", c.Addr(), c.IPAddr(),
c.ServerAddr(), c.ServerIPAddr(), c.TargetPort())
c.Run() c.Run()
} }
} }

View File

@ -7,14 +7,14 @@ import (
"time" "time"
) )
func NewClient(addr string, target string) (*Client, error) { func NewClient(addr string, server string, target int) (*Client, error) {
ipaddr, err := net.ResolveUDPAddr("udp", addr) ipaddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ipaddrTarget, err := net.ResolveIPAddr("ip", target) ipaddrServer, err := net.ResolveIPAddr("ip", server)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -22,8 +22,9 @@ func NewClient(addr string, target string) (*Client, error) {
return &Client{ return &Client{
ipaddr: ipaddr, ipaddr: ipaddr,
addr: addr, addr: addr,
ipaddrTarget: ipaddrTarget, ipaddrServer: ipaddrServer,
addrTarget: target, addrServer: server,
targetPort: (uint16)(target),
}, nil }, nil
} }
@ -31,8 +32,10 @@ type Client struct {
ipaddr *net.UDPAddr ipaddr *net.UDPAddr
addr string addr string
ipaddrTarget *net.IPAddr ipaddrServer *net.IPAddr
addrTarget string addrServer string
targetPort uint16
conn *icmp.PacketConn conn *icmp.PacketConn
listenConn *net.UDPConn listenConn *net.UDPConn
@ -49,12 +52,16 @@ func (p *Client) IPAddr() *net.UDPAddr {
return p.ipaddr return p.ipaddr
} }
func (p *Client) TargetAddr() string { func (p *Client) TargetPort() uint16 {
return p.addrTarget return p.targetPort
} }
func (p *Client) TargetIPAddr() *net.IPAddr { func (p *Client) ServerIPAddr() *net.IPAddr {
return p.ipaddrTarget return p.ipaddrServer
}
func (p *Client) ServerAddr() string {
return p.addrServer
} }
func (p *Client) Run() { func (p *Client) Run() {
@ -98,7 +105,7 @@ func (p *Client) Accept() error {
bytes := make([]byte, 10240) bytes := make([]byte, 10240)
for { for {
p.conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100)) p.listenConn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
n, srcaddr, err := p.listenConn.ReadFromUDP(bytes) n, srcaddr, err := p.listenConn.ReadFromUDP(bytes)
if err != nil { if err != nil {
if neterr, ok := err.(*net.OpError); ok { if neterr, ok := err.(*net.OpError); ok {
@ -120,7 +127,7 @@ func (p *Client) Accept() error {
fmt.Printf("client accept new local %d %s\n", uuid, srcaddr.String()) fmt.Printf("client accept new local %d %s\n", uuid, srcaddr.String())
} }
sendICMP(*p.conn, p.ipaddrTarget, uuid, (uint32)(DATA), bytes[:n]) sendICMP(*p.conn, p.ipaddrServer, p.targetPort, uuid, (uint32)(DATA), bytes[:n])
} }
} }

View File

@ -17,14 +17,11 @@ const (
DATA MSGID = 0xDEADBEEF DATA MSGID = 0xDEADBEEF
) )
const (
protocolICMP = 1
)
// 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 {
ID uint32 ID uint32
TYPE uint32 TYPE uint32
TARGET uint16
Data []byte Data []byte
} }
@ -33,7 +30,7 @@ func (p *MyMsg) Len(proto int) int {
if p == nil { if p == nil {
return 0 return 0
} }
return 8 + len(p.Data) return 10 + len(p.Data)
} }
// Marshal implements the Marshal method of MessageBody interface. // Marshal implements the Marshal method of MessageBody interface.
@ -41,7 +38,8 @@ func (p *MyMsg) Marshal(proto int) ([]byte, error) {
b := make([]byte, p.Len(proto)) b := make([]byte, p.Len(proto))
binary.BigEndian.PutUint32(b[:4], uint32(p.ID)) binary.BigEndian.PutUint32(b[:4], uint32(p.ID))
binary.BigEndian.PutUint32(b[4:8], uint32(p.TYPE)) binary.BigEndian.PutUint32(b[4:8], uint32(p.TYPE))
copy(b[8:], p.Data) binary.BigEndian.PutUint16(b[8:10], uint16(p.TARGET))
copy(b[10:], p.Data)
return b, nil return b, nil
} }
@ -49,8 +47,9 @@ func (p *MyMsg) Marshal(proto int) ([]byte, error) {
func (p *MyMsg) Unmarshal(b []byte) error { func (p *MyMsg) Unmarshal(b []byte) error {
p.ID = binary.BigEndian.Uint32(b[:4]) p.ID = binary.BigEndian.Uint32(b[:4])
p.TYPE = binary.BigEndian.Uint32(b[4:8]) p.TYPE = binary.BigEndian.Uint32(b[4:8])
p.Data = make([]byte, len(b[8:])) p.TARGET = binary.BigEndian.Uint16(b[8:10])
copy(p.Data, b[8:]) p.Data = make([]byte, len(b[10:]))
copy(p.Data, b[10:])
return nil return nil
} }
@ -61,11 +60,12 @@ func UniqueId() uint32 {
return (uint32)(newValue) return (uint32)(newValue)
} }
func sendICMP(conn icmp.PacketConn, target *net.IPAddr, connId uint32, msgType uint32, data []byte) { func sendICMP(conn icmp.PacketConn, server *net.IPAddr, target uint16, connId uint32, msgType uint32, data []byte) {
m := &MyMsg{ m := &MyMsg{
ID: connId, ID: connId,
TYPE: msgType, TYPE: msgType,
TARGET: target,
Data: data, Data: data,
} }
@ -77,18 +77,18 @@ func sendICMP(conn icmp.PacketConn, target *net.IPAddr, connId uint32, msgType u
bytes, err := msg.Marshal(nil) bytes, err := msg.Marshal(nil)
if err != nil { if err != nil {
fmt.Printf("sendICMP Marshal error %s %s\n", target.String(), err) fmt.Printf("sendICMP Marshal error %s %s\n", server.String(), err)
return return
} }
for { for {
if _, err := conn.WriteTo(bytes, target); err != nil { if _, err := conn.WriteTo(bytes, server); err != nil {
if neterr, ok := err.(*net.OpError); ok { if neterr, ok := err.(*net.OpError); ok {
if neterr.Err == syscall.ENOBUFS { if neterr.Err == syscall.ENOBUFS {
continue continue
} }
} }
fmt.Printf("sendICMP WriteTo error %s %s\n", target.String(), err) fmt.Printf("sendICMP WriteTo error %s %s\n", server.String(), err)
} }
break break
} }
@ -124,12 +124,13 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
continue continue
} }
recv <- &Packet{data: my.Data, id: my.ID, src: srcaddr.(*net.IPAddr)} recv <- &Packet{data: my.Data, id: my.ID, target: my.TARGET, src: srcaddr.(*net.IPAddr)}
} }
} }
type Packet struct { type Packet struct {
data []byte data []byte
id uint32 id uint32
target uint16
src *net.IPAddr src *net.IPAddr
} }

View File

@ -4,37 +4,25 @@ import (
"fmt" "fmt"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
"net" "net"
"strconv"
"time" "time"
) )
func NewServer(target string) (*Server, error) { func NewServer() (*Server, error) {
ipaddrTarget, err := net.ResolveUDPAddr("udp", target)
if err != nil {
return nil, err
}
return &Server{ return &Server{
ipaddrTarget: ipaddrTarget,
addrTarget: target,
}, nil }, nil
} }
type Server struct { type Server struct {
ipaddrTarget *net.UDPAddr
addrTarget string
conn *icmp.PacketConn conn *icmp.PacketConn
localConnMap map[uint32]*net.UDPConn localConnMap map[uint32]*Conn
} }
func (p *Server) TargetAddr() string { type Conn struct {
return p.addrTarget ipaddrTarget *net.UDPAddr
} conn *net.UDPConn
id uint32
func (p *Server) TargetIPAddr() *net.UDPAddr {
return p.ipaddrTarget
} }
func (p *Server) Run() { func (p *Server) Run() {
@ -46,7 +34,7 @@ func (p *Server) Run() {
} }
p.conn = conn p.conn = conn
p.localConnMap = make(map[uint32]*net.UDPConn) p.localConnMap = make(map[uint32]*Conn)
recv := make(chan *Packet, 1000) recv := make(chan *Packet, 1000)
go recvICMP(*p.conn, recv) go recvICMP(*p.conn, recv)
@ -66,33 +54,41 @@ func (p *Server) processPacket(packet *Packet) {
id := packet.id id := packet.id
udpConn := p.localConnMap[id] udpConn := p.localConnMap[id]
if udpConn == nil { if udpConn == nil {
targetConn, err := net.ListenUDP("udp", p.ipaddrTarget)
addr := ":" + strconv.Itoa((int)(packet.target))
ipaddrTarget, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
fmt.Printf("Error ResolveUDPAddr for udp addr: %s %s\n", addr, err.Error())
return
}
targetConn, err := net.DialUDP("udp", nil, ipaddrTarget)
if err != nil { if err != nil {
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 = targetConn udpConn = &Conn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id}
p.localConnMap[id] = udpConn p.localConnMap[id] = udpConn
go p.Recv(udpConn, id, packet.src) go p.Recv(udpConn, id, packet.src)
} }
_, err := udpConn.WriteToUDP(packet.data, p.ipaddrTarget) _, err := udpConn.conn.Write(packet.data)
if err != nil { if err != nil {
fmt.Printf("WriteToUDP Error read udp %s\n", err) fmt.Printf("WriteToUDP Error %s\n", err)
p.localConnMap[id] = nil p.Close(udpConn)
return return
} }
} }
func (p *Server) Recv(conn *net.UDPConn, id uint32, src *net.IPAddr) { func (p *Server) Recv(conn *Conn, id uint32, src *net.IPAddr) {
fmt.Println("server waiting target response") fmt.Printf("server waiting target response %s\n", conn.ipaddrTarget.String())
bytes := make([]byte, 10240) bytes := make([]byte, 10240)
for { for {
p.conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100)) conn.conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
n, _, err := conn.ReadFromUDP(bytes) n, _, err := conn.conn.ReadFromUDP(bytes)
if err != nil { if err != nil {
if neterr, ok := err.(*net.OpError); ok { if neterr, ok := err.(*net.OpError); ok {
if neterr.Timeout() { if neterr.Timeout() {
@ -100,12 +96,19 @@ func (p *Server) Recv(conn *net.UDPConn, id uint32, src *net.IPAddr) {
continue continue
} else { } else {
fmt.Printf("ReadFromUDP Error read udp %s\n", err) fmt.Printf("ReadFromUDP Error read udp %s\n", err)
p.localConnMap[id] = nil p.Close(conn)
return return
} }
} }
} }
sendICMP(*p.conn, src, id, (uint32)(DATA), bytes[:n]) sendICMP(*p.conn, src, 0, id, (uint32)(DATA), bytes[:n])
}
}
func (p *Server) Close(conn *Conn) {
if p.localConnMap[conn.id] != nil {
conn.conn.Close()
p.localConnMap[conn.id] = nil
} }
} }