pingtunnel/pingtunnel.go

141 lines
2.9 KiB
Go
Raw Normal View History

2018-12-16 08:56:40 +03:00
package pingtunnel
import (
2018-12-18 10:36:59 +03:00
"crypto/md5"
"crypto/rand"
"encoding/base64"
2018-12-16 08:56:40 +03:00
"encoding/binary"
2018-12-18 10:36:59 +03:00
"encoding/hex"
2019-10-20 11:27:03 +03:00
"github.com/esrrhs/go-engine/src/loggo"
2019-10-22 16:04:25 +03:00
"github.com/golang/protobuf/proto"
2018-12-17 14:06:46 +03:00
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
2018-12-18 10:36:59 +03:00
"io"
2018-12-17 14:06:46 +03:00
"net"
"syscall"
"time"
2018-12-16 08:56:40 +03:00
)
2018-12-23 02:02:57 +03:00
func sendICMP(id int, sequence int, conn icmp.PacketConn, server *net.IPAddr, target string,
2019-10-22 16:27:21 +03:00
connId string, msgType uint32, data []byte, sproto int, rproto int, key int,
2019-10-22 16:04:25 +03:00
tcpmode int, tcpmode_buffer_size int, tcpmode_maxwin int, tcpmode_resend_time int) {
2018-12-17 14:06:46 +03:00
m := &MyMsg{
2019-10-22 16:04:25 +03:00
Id: connId,
Type: (int32)(msgType),
Target: target,
Data: data,
Rproto: (int32)(rproto),
Key: (int32)(key),
Tcpmode: (int32)(tcpmode),
TcpmodeBuffersize: (int32)(tcpmode_buffer_size),
TcpmodeMaxwin: (int32)(tcpmode_maxwin),
TcpmodeResendTimems: (int32)(tcpmode_resend_time),
2018-12-17 14:06:46 +03:00
}
2019-10-22 16:04:25 +03:00
mb, err := proto.Marshal(m)
if err != nil {
loggo.Error("sendICMP Marshal MyMsg error %s %s", server.String(), err)
return
}
2018-12-21 10:52:34 +03:00
body := &icmp.Echo{
ID: id,
Seq: sequence,
Data: mb,
}
2018-12-17 14:06:46 +03:00
msg := &icmp.Message{
2018-12-19 09:38:44 +03:00
Type: (ipv4.ICMPType)(sproto),
2018-12-17 14:06:46 +03:00
Code: 0,
2018-12-21 10:52:34 +03:00
Body: body,
2018-12-17 14:06:46 +03:00
}
2018-12-16 08:56:40 +03:00
2018-12-17 14:06:46 +03:00
bytes, err := msg.Marshal(nil)
if err != nil {
2019-10-20 11:27:03 +03:00
loggo.Error("sendICMP Marshal error %s %s", server.String(), err)
2018-12-17 14:06:46 +03:00
return
2018-12-16 08:56:40 +03:00
}
2018-12-17 14:06:46 +03:00
for {
2018-12-18 06:39:16 +03:00
if _, err := conn.WriteTo(bytes, server); err != nil {
2018-12-17 14:06:46 +03:00
if neterr, ok := err.(*net.OpError); ok {
if neterr.Err == syscall.ENOBUFS {
continue
}
}
2019-10-20 11:27:03 +03:00
loggo.Error("sendICMP WriteTo error %s %s", server.String(), err)
2018-12-17 14:06:46 +03:00
}
break
}
return
2018-12-17 10:21:15 +03:00
}
2018-12-17 14:06:46 +03:00
func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
bytes := make([]byte, 10240)
for {
conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100))
n, srcaddr, err := conn.ReadFrom(bytes)
if err != nil {
if neterr, ok := err.(*net.OpError); ok {
if neterr.Timeout() {
// Read timeout
continue
} else {
2019-10-20 11:27:03 +03:00
loggo.Error("Error read icmp message %s", err)
2018-12-17 14:06:46 +03:00
continue
}
}
}
2018-12-21 11:09:54 +03:00
echoId := int(binary.BigEndian.Uint16(bytes[4:6]))
echoSeq := int(binary.BigEndian.Uint16(bytes[6:8]))
2019-10-18 16:30:54 +03:00
my := &MyMsg{}
2019-10-22 16:04:25 +03:00
err = proto.Unmarshal(bytes[8:n], my)
if err != nil {
loggo.Debug("Unmarshal MyMsg error: %s", err)
2018-12-17 14:06:46 +03:00
continue
}
2018-12-19 09:38:44 +03:00
if my.Data == nil {
2019-10-22 16:04:25 +03:00
loggo.Info("processPacket data nil %s", my.Id)
2018-12-19 09:38:44 +03:00
return
}
2019-10-22 16:04:25 +03:00
recv <- &Packet{my: my,
src: srcaddr.(*net.IPAddr),
echoId: echoId, echoSeq: echoSeq}
2018-12-17 14:06:46 +03:00
}
2018-12-17 10:21:15 +03:00
}
2018-12-17 14:06:46 +03:00
type Packet struct {
2019-10-22 16:04:25 +03:00
my *MyMsg
2018-12-19 10:00:30 +03:00
src *net.IPAddr
2018-12-21 11:09:54 +03:00
echoId int
echoSeq int
2018-12-16 08:56:40 +03:00
}
2018-12-18 10:36:59 +03:00
func UniqueId() string {
b := make([]byte, 48)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
return ""
}
return GetMd5String(base64.URLEncoding.EncodeToString(b))
}
func GetMd5String(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
2018-12-23 02:02:57 +03:00
2019-10-18 16:30:54 +03:00
const (
FRAME_MAX_SIZE int = 888
2019-10-19 17:36:17 +03:00
FRAME_MAX_ID int = 999
)