fix
This commit is contained in:
parent
429083487b
commit
99b477a7dd
50
cmd/main.go
50
cmd/main.go
@ -7,39 +7,53 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var usage = `
|
var usage = `
|
||||||
|
通过伪造ping,把udp流量通过远程服务器转发到目的服务器上。用于突破某些运营商封锁UDP流量。
|
||||||
|
By forging ping, the udp traffic is forwarded to the destination server through the remote server. Used to break certain operators to block UDP traffic.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
pingtunnel -type server
|
pingtunnel -type server
|
||||||
|
|
||||||
pingtunnel -type client -l LOCAL_IP:4455 -s SERVER_IP -t 4455
|
pingtunnel -type client -l LOCAL_IP:4455 -s SERVER_IP -t SERVER_IP:4455
|
||||||
|
|
||||||
|
-type 服务器或者客户端
|
||||||
|
client or server
|
||||||
|
|
||||||
|
-l 本地的地址,发到这个端口的流量将转发到服务器
|
||||||
|
Local address, traffic sent to this port will be forwarded to the server
|
||||||
|
|
||||||
|
-s 服务器的地址,流量将通过隧道转发到这个服务器
|
||||||
|
The address of the server, the traffic will be forwarded to this server through the tunnel
|
||||||
|
|
||||||
|
-t 远端服务器转发的目的地址,流量将转发到这个地址
|
||||||
|
Destination address forwarded by the remote server, traffic will be forwarded to this address
|
||||||
|
|
||||||
|
-timeout 本地记录连接超时的时间,单位是秒
|
||||||
|
The time when the local record connection timed out, in seconds
|
||||||
`
|
`
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("start...")
|
|
||||||
|
|
||||||
t := flag.String("type", "client", "client or server")
|
t := flag.String("type", "", "client or server")
|
||||||
listen := flag.String("l", ":4455", "listen addr")
|
listen := flag.String("l", "", "listen addr")
|
||||||
target := flag.Int("t", 4455, "target port")
|
target := flag.String("t", "", "target addr")
|
||||||
server := flag.String("s", "127.0.0.1", "server addr")
|
server := flag.String("s", "", "server addr")
|
||||||
|
timeout := flag.Int("timeout", 60, "conn timeout")
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
fmt.Printf(usage)
|
fmt.Printf(usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if flag.NArg() != 0 {
|
if (*t != "client" && *t != "server") || (*t == "client" && (len(*listen) == 0 || len(*target) == 0 || len(*server) == 0)) {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("type %s\n", *t)
|
fmt.Println("start...")
|
||||||
fmt.Printf("listen %s\n", *listen)
|
|
||||||
fmt.Printf("server %s\n", *server)
|
|
||||||
fmt.Printf("target port %d\n", *target)
|
|
||||||
|
|
||||||
if *t == "server" {
|
if *t == "server" {
|
||||||
s, err := pingtunnel.NewServer()
|
s, err := pingtunnel.NewServer(*timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: %s\n", err.Error())
|
fmt.Printf("ERROR: %s\n", err.Error())
|
||||||
return
|
return
|
||||||
@ -48,13 +62,19 @@ func main() {
|
|||||||
s.Run()
|
s.Run()
|
||||||
}
|
}
|
||||||
if *t == "client" {
|
if *t == "client" {
|
||||||
c, err := pingtunnel.NewClient(*listen, *server, *target)
|
|
||||||
|
fmt.Printf("type %s\n", *t)
|
||||||
|
fmt.Printf("listen %s\n", *listen)
|
||||||
|
fmt.Printf("server %s\n", *server)
|
||||||
|
fmt.Printf("target %s\n", *target)
|
||||||
|
|
||||||
|
c, err := pingtunnel.NewClient(*listen, *server, *target, *timeout)
|
||||||
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) Server %s (%s) TargetPort %d:\n", c.Addr(), c.IPAddr(),
|
fmt.Printf("Client Listen %s (%s) Server %s (%s) TargetPort %s:\n", c.Addr(), c.IPAddr(),
|
||||||
c.ServerAddr(), c.ServerIPAddr(), c.TargetPort())
|
c.ServerAddr(), c.ServerIPAddr(), c.TargetAddr())
|
||||||
c.Run()
|
c.Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewClient(addr string, server string, target int) (*Client, error) {
|
func NewClient(addr string, server string, target string, timeout int) (*Client, error) {
|
||||||
|
|
||||||
ipaddr, err := net.ResolveUDPAddr("udp", addr)
|
ipaddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -24,24 +24,33 @@ func NewClient(addr string, server string, target int) (*Client, error) {
|
|||||||
addr: addr,
|
addr: addr,
|
||||||
ipaddrServer: ipaddrServer,
|
ipaddrServer: ipaddrServer,
|
||||||
addrServer: server,
|
addrServer: server,
|
||||||
targetPort: (uint16)(target),
|
targetAddr: target,
|
||||||
|
timeout: timeout,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
timeout int
|
||||||
|
|
||||||
ipaddr *net.UDPAddr
|
ipaddr *net.UDPAddr
|
||||||
addr string
|
addr string
|
||||||
|
|
||||||
ipaddrServer *net.IPAddr
|
ipaddrServer *net.IPAddr
|
||||||
addrServer string
|
addrServer string
|
||||||
|
|
||||||
targetPort uint16
|
targetAddr string
|
||||||
|
|
||||||
conn *icmp.PacketConn
|
conn *icmp.PacketConn
|
||||||
listenConn *net.UDPConn
|
listenConn *net.UDPConn
|
||||||
|
|
||||||
localConnToIdMap map[string]uint32
|
localAddrToConnMap map[string]*ClientConn
|
||||||
localIdToConnMap map[uint32]*net.UDPAddr
|
localIdToConnMap map[string]*ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientConn struct {
|
||||||
|
ipaddr *net.UDPAddr
|
||||||
|
id string
|
||||||
|
activeTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Client) Addr() string {
|
func (p *Client) Addr() string {
|
||||||
@ -52,8 +61,8 @@ func (p *Client) IPAddr() *net.UDPAddr {
|
|||||||
return p.ipaddr
|
return p.ipaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Client) TargetPort() uint16 {
|
func (p *Client) TargetAddr() string {
|
||||||
return p.targetPort
|
return p.targetAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Client) ServerIPAddr() *net.IPAddr {
|
func (p *Client) ServerIPAddr() *net.IPAddr {
|
||||||
@ -82,16 +91,21 @@ func (p *Client) Run() {
|
|||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
p.listenConn = listener
|
p.listenConn = listener
|
||||||
|
|
||||||
p.localConnToIdMap = make(map[string]uint32)
|
p.localAddrToConnMap = make(map[string]*ClientConn)
|
||||||
p.localIdToConnMap = make(map[uint32]*net.UDPAddr)
|
p.localIdToConnMap = make(map[string]*ClientConn)
|
||||||
|
|
||||||
go p.Accept()
|
go p.Accept()
|
||||||
|
|
||||||
recv := make(chan *Packet, 1000)
|
recv := make(chan *Packet, 1000)
|
||||||
go recvICMP(*p.conn, recv)
|
go recvICMP(*p.conn, recv)
|
||||||
|
|
||||||
|
interval := time.NewTicker(time.Second)
|
||||||
|
defer interval.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
case <-interval.C:
|
||||||
|
p.checkTimeoutConn()
|
||||||
case r := <-recv:
|
case r := <-recv:
|
||||||
p.processPacket(r)
|
p.processPacket(r)
|
||||||
}
|
}
|
||||||
@ -119,33 +133,58 @@ func (p *Client) Accept() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid := p.localConnToIdMap[srcaddr.String()]
|
now := time.Now()
|
||||||
if uuid == 0 {
|
clientConn := p.localAddrToConnMap[srcaddr.String()]
|
||||||
uuid = UniqueId()
|
if clientConn == nil {
|
||||||
p.localConnToIdMap[srcaddr.String()] = uuid
|
uuid := UniqueId()
|
||||||
p.localIdToConnMap[uuid] = srcaddr
|
clientConn = &ClientConn{ipaddr: srcaddr, id: uuid, activeTime: now}
|
||||||
fmt.Printf("client accept new local %d %s\n", uuid, srcaddr.String())
|
p.localAddrToConnMap[srcaddr.String()] = clientConn
|
||||||
|
p.localIdToConnMap[uuid] = clientConn
|
||||||
|
fmt.Printf("client accept new local %s %s\n", uuid, srcaddr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
sendICMP(*p.conn, p.ipaddrServer, p.targetPort, uuid, (uint32)(DATA), bytes[:n])
|
clientConn.activeTime = now
|
||||||
|
sendICMP(*p.conn, p.ipaddrServer, p.targetAddr, clientConn.id, (uint32)(DATA), bytes[:n])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Client) processPacket(packet *Packet) {
|
func (p *Client) processPacket(packet *Packet) {
|
||||||
|
|
||||||
fmt.Printf("processPacket %d %s %d\n", packet.id, packet.src.String(), len(packet.data))
|
fmt.Printf("processPacket %s %s %d\n", packet.id, packet.src.String(), len(packet.data))
|
||||||
|
|
||||||
addr := p.localIdToConnMap[packet.id]
|
clientConn := p.localIdToConnMap[packet.id]
|
||||||
if addr == nil {
|
if clientConn == nil {
|
||||||
fmt.Printf("processPacket no conn %d \n", packet.id)
|
fmt.Printf("processPacket no conn %s \n", packet.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr := clientConn.ipaddr
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
clientConn.activeTime = now
|
||||||
|
|
||||||
_, err := p.listenConn.WriteToUDP(packet.data, addr)
|
_, err := p.listenConn.WriteToUDP(packet.data, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("WriteToUDP Error read udp %s\n", err)
|
fmt.Printf("WriteToUDP Error read udp %s\n", err)
|
||||||
p.localConnToIdMap[addr.String()] = 0
|
p.Close(clientConn)
|
||||||
p.localIdToConnMap[packet.id] = nil
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Client) Close(clientConn *ClientConn) {
|
||||||
|
if p.localIdToConnMap[clientConn.id] != nil {
|
||||||
|
delete(p.localIdToConnMap, clientConn.id)
|
||||||
|
delete(p.localAddrToConnMap, clientConn.ipaddr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Client) checkTimeoutConn() {
|
||||||
|
now := time.Now()
|
||||||
|
for id, conn := range p.localIdToConnMap {
|
||||||
|
diff := now.Sub(conn.activeTime)
|
||||||
|
if diff > time.Second*(time.Duration(p.timeout)) {
|
||||||
|
fmt.Printf("close inactive conn %s %s\n", id, conn.ipaddr.String())
|
||||||
|
p.Close(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package pingtunnel
|
package pingtunnel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"sync/atomic"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -19,9 +23,9 @@ const (
|
|||||||
|
|
||||||
// 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
|
|
||||||
TYPE uint32
|
TYPE uint32
|
||||||
TARGET uint16
|
ID string
|
||||||
|
TARGET string
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,37 +34,61 @@ func (p *MyMsg) Len(proto int) int {
|
|||||||
if p == nil {
|
if p == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return 10 + len(p.Data)
|
return 4 + p.LenString(p.ID) + p.LenString(p.TARGET) + len(p.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyMsg) LenString(s string) int {
|
||||||
|
return 2 + len(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal implements the Marshal method of MessageBody interface.
|
// Marshal implements the Marshal method of MessageBody interface.
|
||||||
func (p *MyMsg) Marshal(proto int) ([]byte, error) {
|
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:8], uint32(p.TYPE))
|
binary.BigEndian.PutUint32(b[:4], uint32(p.TYPE))
|
||||||
binary.BigEndian.PutUint16(b[8:10], uint16(p.TARGET))
|
|
||||||
copy(b[10:], p.Data)
|
id := p.MarshalString(p.ID)
|
||||||
|
copy(b[4:], id)
|
||||||
|
|
||||||
|
target := p.MarshalString(p.TARGET)
|
||||||
|
copy(b[4+p.LenString(p.ID):], target)
|
||||||
|
|
||||||
|
copy(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):], p.Data)
|
||||||
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *MyMsg) MarshalString(s string) []byte {
|
||||||
|
b := make([]byte, p.LenString(s))
|
||||||
|
binary.BigEndian.PutUint16(b[:2], uint16(len(s)))
|
||||||
|
copy(b[2:], []byte(s))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// Marshal implements the Marshal method of MessageBody interface.
|
// Marshal implements the Marshal method of MessageBody interface.
|
||||||
func (p *MyMsg) Unmarshal(b []byte) error {
|
func (p *MyMsg) Unmarshal(b []byte) error {
|
||||||
p.ID = binary.BigEndian.Uint32(b[:4])
|
|
||||||
p.TYPE = binary.BigEndian.Uint32(b[4:8])
|
p.TYPE = binary.BigEndian.Uint32(b[:4])
|
||||||
p.TARGET = binary.BigEndian.Uint16(b[8:10])
|
|
||||||
p.Data = make([]byte, len(b[10:]))
|
p.ID = p.UnmarshalString(b[4:])
|
||||||
copy(p.Data, b[10:])
|
|
||||||
|
p.TARGET = p.UnmarshalString(b[4+p.LenString(p.ID):])
|
||||||
|
|
||||||
|
p.Data = make([]byte, len(b[4+p.LenString(p.ID)+p.LenString(p.TARGET):]))
|
||||||
|
copy(p.Data, b[4+p.LenString(p.ID)+p.LenString(p.TARGET):])
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var uuid uint32
|
func (p *MyMsg) UnmarshalString(b []byte) string {
|
||||||
|
len := binary.BigEndian.Uint16(b[:2])
|
||||||
func UniqueId() uint32 {
|
data := make([]byte, len)
|
||||||
newValue := atomic.AddUint32(&uuid, 1)
|
copy(data, b[2:])
|
||||||
return (uint32)(newValue)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendICMP(conn icmp.PacketConn, server *net.IPAddr, target uint16, connId uint32, msgType uint32, data []byte) {
|
func sendICMP(conn icmp.PacketConn, server *net.IPAddr, target string, connId string, msgType uint32, data []byte) {
|
||||||
|
|
||||||
m := &MyMsg{
|
m := &MyMsg{
|
||||||
ID: connId,
|
ID: connId,
|
||||||
@ -130,7 +158,22 @@ func recvICMP(conn icmp.PacketConn, recv chan<- *Packet) {
|
|||||||
|
|
||||||
type Packet struct {
|
type Packet struct {
|
||||||
data []byte
|
data []byte
|
||||||
id uint32
|
id string
|
||||||
target uint16
|
target string
|
||||||
src *net.IPAddr
|
src *net.IPAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
@ -4,25 +4,28 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServer() (*Server, error) {
|
func NewServer(timeout int) (*Server, error) {
|
||||||
return &Server{
|
return &Server{
|
||||||
|
timeout: timeout,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
timeout int
|
||||||
|
|
||||||
conn *icmp.PacketConn
|
conn *icmp.PacketConn
|
||||||
|
|
||||||
localConnMap map[uint32]*Conn
|
localConnMap map[string]*ServerConn
|
||||||
}
|
}
|
||||||
|
|
||||||
type Conn struct {
|
type ServerConn struct {
|
||||||
ipaddrTarget *net.UDPAddr
|
ipaddrTarget *net.UDPAddr
|
||||||
conn *net.UDPConn
|
conn *net.UDPConn
|
||||||
id uint32
|
id string
|
||||||
|
activeTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Server) Run() {
|
func (p *Server) Run() {
|
||||||
@ -34,13 +37,18 @@ func (p *Server) Run() {
|
|||||||
}
|
}
|
||||||
p.conn = conn
|
p.conn = conn
|
||||||
|
|
||||||
p.localConnMap = make(map[uint32]*Conn)
|
p.localConnMap = make(map[string]*ServerConn)
|
||||||
|
|
||||||
recv := make(chan *Packet, 1000)
|
recv := make(chan *Packet, 1000)
|
||||||
go recvICMP(*p.conn, recv)
|
go recvICMP(*p.conn, recv)
|
||||||
|
|
||||||
|
interval := time.NewTicker(time.Second)
|
||||||
|
defer interval.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
case <-interval.C:
|
||||||
|
p.checkTimeoutConn()
|
||||||
case r := <-recv:
|
case r := <-recv:
|
||||||
p.processPacket(r)
|
p.processPacket(r)
|
||||||
}
|
}
|
||||||
@ -49,13 +57,15 @@ func (p *Server) Run() {
|
|||||||
|
|
||||||
func (p *Server) processPacket(packet *Packet) {
|
func (p *Server) processPacket(packet *Packet) {
|
||||||
|
|
||||||
fmt.Printf("processPacket %d %s %d\n", packet.id, packet.src.String(), len(packet.data))
|
fmt.Printf("processPacket %s %s %d\n", packet.id, packet.src.String(), len(packet.data))
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
id := packet.id
|
id := packet.id
|
||||||
udpConn := p.localConnMap[id]
|
udpConn := p.localConnMap[id]
|
||||||
if udpConn == nil {
|
if udpConn == nil {
|
||||||
|
|
||||||
addr := ":" + strconv.Itoa((int)(packet.target))
|
addr := packet.target
|
||||||
ipaddrTarget, err := net.ResolveUDPAddr("udp", addr)
|
ipaddrTarget, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error ResolveUDPAddr for udp addr: %s %s\n", addr, err.Error())
|
fmt.Printf("Error ResolveUDPAddr for udp addr: %s %s\n", addr, err.Error())
|
||||||
@ -67,11 +77,13 @@ func (p *Server) processPacket(packet *Packet) {
|
|||||||
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 = &Conn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id}
|
udpConn = &ServerConn{conn: targetConn, ipaddrTarget: ipaddrTarget, id: id, activeTime: now}
|
||||||
p.localConnMap[id] = udpConn
|
p.localConnMap[id] = udpConn
|
||||||
go p.Recv(udpConn, id, packet.src)
|
go p.Recv(udpConn, id, packet.src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
udpConn.activeTime = now
|
||||||
|
|
||||||
_, 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)
|
||||||
@ -80,9 +92,9 @@ func (p *Server) processPacket(packet *Packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Server) Recv(conn *Conn, id uint32, src *net.IPAddr) {
|
func (p *Server) Recv(conn *ServerConn, id string, src *net.IPAddr) {
|
||||||
|
|
||||||
fmt.Printf("server waiting target response %s\n", conn.ipaddrTarget.String())
|
fmt.Printf("server waiting target response %s -> %s %s\n", conn.ipaddrTarget.String(), conn.id, conn.conn.LocalAddr().String())
|
||||||
|
|
||||||
bytes := make([]byte, 10240)
|
bytes := make([]byte, 10240)
|
||||||
|
|
||||||
@ -102,13 +114,29 @@ func (p *Server) Recv(conn *Conn, id uint32, src *net.IPAddr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendICMP(*p.conn, src, 0, id, (uint32)(DATA), bytes[:n])
|
now := time.Now()
|
||||||
|
conn.activeTime = now
|
||||||
|
|
||||||
|
sendICMP(*p.conn, src, "", id, (uint32)(DATA), bytes[:n])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Server) Close(conn *Conn) {
|
func (p *Server) Close(conn *ServerConn) {
|
||||||
if p.localConnMap[conn.id] != nil {
|
if p.localConnMap[conn.id] != nil {
|
||||||
conn.conn.Close()
|
conn.conn.Close()
|
||||||
p.localConnMap[conn.id] = nil
|
delete(p.localConnMap, conn.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Server) checkTimeoutConn() {
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
for id, conn := range p.localConnMap {
|
||||||
|
diff := now.Sub(conn.activeTime)
|
||||||
|
if diff > time.Second*(time.Duration(p.timeout)) {
|
||||||
|
fmt.Printf("close inactive conn %s %s\n", id, conn.ipaddrTarget.String())
|
||||||
|
p.Close(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user