fix
This commit is contained in:
parent
a8910116d2
commit
429083487b
19
cmd/main.go
19
cmd/main.go
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,15 +17,12 @@ 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
|
||||||
Data []byte
|
TARGET uint16
|
||||||
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len implements the Len method of MessageBody interface.
|
// Len implements the Len method of MessageBody interface.
|
||||||
@ -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,12 +60,13 @@ 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,
|
||||||
Data: data,
|
TARGET: target,
|
||||||
|
Data: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &icmp.Message{
|
msg := &icmp.Message{
|
||||||
@ -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
|
||||||
src *net.IPAddr
|
target uint16
|
||||||
|
src *net.IPAddr
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user