diff --git a/client.go b/client.go index 3cadb31..92e38e6 100644 --- a/client.go +++ b/client.go @@ -24,7 +24,6 @@ func NewClient(addr string, server string, target string, timeout int, sproto in r := rand.New(rand.NewSource(time.Now().UnixNano())) return &Client{ id: r.Intn(math.MaxInt16), - r: r, ipaddr: ipaddr, addr: addr, ipaddrServer: ipaddrServer, @@ -37,8 +36,8 @@ func NewClient(addr string, server string, target string, timeout int, sproto in } type Client struct { - id int - r *rand.Rand + id int + sequence int timeout int sproto int @@ -164,7 +163,9 @@ func (p *Client) Accept() error { } clientConn.activeTime = now - sendICMP(p.id, p.r.Intn(math.MaxInt16), *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n], p.sproto, p.rproto) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n], p.sproto, p.rproto) + + p.sequence++ p.sendPacket++ p.sendPacketSize += (uint64)(n) @@ -234,11 +235,12 @@ func (p *Client) checkTimeoutConn() { } func (p *Client) ping() { - if p.sendPacket == 0 && p.recvPacket == 0 { + if p.sendPacket == 0 { now := time.Now() b, _ := now.MarshalBinary() - sendICMP(p.id, p.r.Intn(math.MaxInt16), *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(PING), b, p.sproto, p.rproto) - fmt.Printf("ping %s %s %d %d\n", p.addrServer, now.String(), p.sproto, p.rproto) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, "", (uint32)(PING), b, p.sproto, p.rproto) + fmt.Printf("ping %s %s %d %d %d %d\n", p.addrServer, now.String(), p.sproto, p.rproto, p.id, p.sequence) + p.sequence++ } } diff --git a/pingtunnel.go b/pingtunnel.go index 71ee706..fd1c209 100644 --- a/pingtunnel.go +++ b/pingtunnel.go @@ -190,6 +190,9 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) { } } + echoId := int(binary.BigEndian.Uint16(bytes[4:6])) + echoSeq := int(binary.BigEndian.Uint16(bytes[6:8])) + my := &MyMsg{ } my.Unmarshal(bytes[8:n]) @@ -204,7 +207,9 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) { return } - recv <- &Packet{msgType: my.TYPE, data: my.Data, id: my.ID, target: my.TARGET, src: srcaddr.(*net.IPAddr), rproto: (int)((int16)(my.RPROTO))} + recv <- &Packet{msgType: my.TYPE, data: my.Data, id: my.ID, target: my.TARGET, + src: srcaddr.(*net.IPAddr), rproto: (int)((int16)(my.RPROTO)), + echoId: echoId, echoSeq: echoSeq} } } @@ -215,6 +220,8 @@ type Packet struct { target string src *net.IPAddr rproto int + echoId int + echoSeq int } func UniqueId() string { diff --git a/server.go b/server.go index f0179af..1ccd7e9 100644 --- a/server.go +++ b/server.go @@ -3,25 +3,17 @@ package pingtunnel import ( "fmt" "golang.org/x/net/icmp" - "math" - "math/rand" "net" "time" ) func NewServer(timeout int) (*Server, error) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) return &Server{ - id: r.Intn(math.MaxInt16), - r: r, timeout: timeout, }, nil } type Server struct { - id int - r *rand.Rand - timeout int conn *icmp.PacketConn @@ -41,6 +33,8 @@ type ServerConn struct { activeTime time.Time close bool rproto int + echoId int + echoSeq int } func (p *Server) Run() { @@ -76,8 +70,8 @@ func (p *Server) processPacket(packet *Packet) { if packet.msgType == PING { t := time.Time{} t.UnmarshalBinary(packet.data) - fmt.Printf("ping from %s %s %d\n", packet.src.String(), t.String(), packet.rproto) - sendICMP(p.id, p.r.Intn(math.MaxInt16), *p.conn, packet.src, "", "", (uint32)(PING), packet.data, packet.rproto, -1) + fmt.Printf("ping from %s %s %d %d %d\n", packet.src.String(), t.String(), packet.rproto, packet.echoId, packet.echoSeq) + sendICMP(packet.echoId, packet.echoSeq, *p.conn, packet.src, "", "", (uint32)(PING), packet.data, packet.rproto, -1) return } @@ -107,6 +101,8 @@ func (p *Server) processPacket(packet *Packet) { } udpConn.activeTime = now + udpConn.echoId = packet.echoId + udpConn.echoSeq = packet.echoSeq _, err := udpConn.conn.Write(packet.data) if err != nil { @@ -144,7 +140,7 @@ func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) { now := time.Now() conn.activeTime = now - sendICMP(p.id, p.r.Intn(math.MaxInt16), *p.conn, src, "", id, (uint32)(DATA), bytes[:n], conn.rproto, -1) + sendICMP(conn.echoId, conn.echoSeq, *p.conn, src, "", id, (uint32)(DATA), bytes[:n], conn.rproto, -1) p.sendPacket++ p.sendPacketSize += (uint64)(n)