This commit is contained in:
esrrhs 2018-12-22 16:42:45 +08:00
parent d72a7ff774
commit b76965fe52
5 changed files with 52 additions and 5 deletions

View File

@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/src/github.com/esrrhs/pingtunnel" vcs="Git" />
</component> </component>
</project> </project>

View File

@ -1,6 +1,7 @@
package pingtunnel package pingtunnel
import ( import (
"encoding/binary"
"fmt" "fmt"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
"math" "math"
@ -9,7 +10,7 @@ import (
"time" "time"
) )
func NewClient(addr string, server string, target string, timeout int, sproto int, rproto int) (*Client, error) { func NewClient(addr string, server string, target string, timeout int, sproto int, rproto int, hb int) (*Client, error) {
ipaddr, err := net.ResolveUDPAddr("udp", addr) ipaddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil { if err != nil {
@ -32,6 +33,7 @@ func NewClient(addr string, server string, target string, timeout int, sproto in
timeout: timeout, timeout: timeout,
sproto: sproto, sproto: sproto,
rproto: rproto, rproto: rproto,
hb: hb,
}, nil }, nil
} }
@ -42,6 +44,7 @@ type Client struct {
timeout int timeout int
sproto int sproto int
rproto int rproto int
hb int
ipaddr *net.UDPAddr ipaddr *net.UDPAddr
addr string addr string
@ -61,6 +64,8 @@ type Client struct {
recvPacket uint64 recvPacket uint64
sendPacketSize uint64 sendPacketSize uint64
recvPacketSize uint64 recvPacketSize uint64
sendHBPacket uint64
} }
type ClientConn struct { type ClientConn struct {
@ -119,12 +124,24 @@ func (p *Client) Run() {
interval := time.NewTicker(time.Second) interval := time.NewTicker(time.Second)
defer interval.Stop() defer interval.Stop()
inter := 1000
if p.hb > 0 {
inter := 1000 / p.hb
if inter <= 0 {
inter = 1
}
}
intervalHB := time.NewTicker(time.Millisecond * (time.Duration)(inter))
defer intervalHB.Stop()
for { for {
select { select {
case <-interval.C: case <-interval.C:
p.checkTimeoutConn() p.checkTimeoutConn()
p.ping() p.ping()
p.showNet() p.showNet()
case <-intervalHB.C:
p.heartbeat()
case r := <-recv: case r := <-recv:
p.processPacket(r) p.processPacket(r)
} }
@ -235,7 +252,7 @@ func (p *Client) checkTimeoutConn() {
} }
func (p *Client) ping() { func (p *Client) ping() {
if p.sendPacket == 0 { if p.sendPacket == 0 && p.recvPacket == 0 {
now := time.Now() now := time.Now()
b, _ := now.MarshalBinary() b, _ := now.MarshalBinary()
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(PING), b, p.sproto, p.rproto) sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(PING), b, p.sproto, p.rproto)
@ -245,9 +262,27 @@ func (p *Client) ping() {
} }
func (p *Client) showNet() { func (p *Client) showNet() {
fmt.Printf("send %dPacket/s %dKB/s recv %dPacket/s %dKB/s\n", p.sendPacket, p.sendPacketSize/1024, p.recvPacket, p.recvPacketSize/1024) fmt.Printf("send %dPacket/s %dKB/s recv %dPacket/s %dKB/s HB %d/s\n",
p.sendPacket, p.sendPacketSize/1024, p.recvPacket, p.recvPacketSize/1024, p.sendHBPacket)
p.sendPacket = 0 p.sendPacket = 0
p.recvPacket = 0 p.recvPacket = 0
p.sendPacketSize = 0 p.sendPacketSize = 0
p.recvPacketSize = 0 p.recvPacketSize = 0
p.sendHBPacket = 0
}
func (p *Client) heartbeat() {
if p.hb > 0 {
for _, conn := range p.localIdToConnMap {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b[:4], rand.Uint32())
sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, conn.id, (uint32)(HB), b, p.sproto, p.rproto)
p.sequence++
p.sendHBPacket++
}
}
} }

View File

@ -36,6 +36,8 @@ Usage:
-rproto 客户端接收ping协议的协议默认是0 -rproto 客户端接收ping协议的协议默认是0
The protocol that the client receives the ping. The default is 0. The protocol that the client receives the ping. The default is 0.
-hb 客户端保持每秒发到服务器的心跳包用于在某些网络下更新服务器的id和seq以接收到服务器的reply
` `
func main() { func main() {
@ -47,6 +49,7 @@ func main() {
timeout := flag.Int("timeout", 60, "conn timeout") timeout := flag.Int("timeout", 60, "conn timeout")
sproto := flag.Int("sproto", 8, "send ping proto") sproto := flag.Int("sproto", 8, "send ping proto")
rproto := flag.Int("rproto", 0, "recv ping proto") rproto := flag.Int("rproto", 0, "recv ping proto")
hb := flag.Int("hb", 0, "client heartbeat")
flag.Usage = func() { flag.Usage = func() {
fmt.Printf(usage) fmt.Printf(usage)
} }
@ -76,7 +79,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, *sproto, *rproto) c, err := pingtunnel.NewClient(*listen, *server, *target, *timeout, *sproto, *rproto, *hb)
if err != nil { if err != nil {
fmt.Printf("ERROR: %s\n", err.Error()) fmt.Printf("ERROR: %s\n", err.Error())
return return

View File

@ -18,6 +18,7 @@ import (
const ( const (
DATA uint32 = 0x01010101 DATA uint32 = 0x01010101
PING uint32 = 0x02020202 PING uint32 = 0x02020202
HB uint32 = 0x03030303
END uint32 = 0xAAAABBBB END uint32 = 0xAAAABBBB
) )
@ -197,7 +198,8 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
} }
my.Unmarshal(bytes[8:n]) my.Unmarshal(bytes[8:n])
if (my.TYPE != (uint32)(DATA) && my.TYPE != (uint32)(PING)) || my.ENDTYPE != (uint32)(END) { if (my.TYPE != (uint32)(DATA) && my.TYPE != (uint32)(PING) && my.TYPE != (uint32)(HB)) ||
my.ENDTYPE != (uint32)(END) {
//fmt.Printf("processPacket diff type %s %d %d \n", my.ID, my.TYPE, my.ENDTYPE) //fmt.Printf("processPacket diff type %s %d %d \n", my.ID, my.TYPE, my.ENDTYPE)
continue continue
} }

View File

@ -104,6 +104,12 @@ func (p *Server) processPacket(packet *Packet) {
udpConn.echoId = packet.echoId udpConn.echoId = packet.echoId
udpConn.echoSeq = packet.echoSeq udpConn.echoSeq = packet.echoSeq
if packet.msgType == HB {
udpConn.echoId = packet.echoId
udpConn.echoSeq = packet.echoSeq
return
}
_, err := udpConn.conn.Write(packet.data) _, err := udpConn.conn.Write(packet.data)
if err != nil { if err != nil {
fmt.Printf("WriteToUDP Error %s\n", err) fmt.Printf("WriteToUDP Error %s\n", err)