-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharm.go
116 lines (100 loc) · 2.22 KB
/
arm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package mdp
import (
"encoding/binary"
"math/rand"
"net"
"reflect"
"time"
"github.com/poohvpn/icmdp"
"github.com/poohvpn/pooh"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
const (
sessionIDSize = 4
nodeIDSize = 4
natTimeout = 30 * time.Second
queueSize = 1024
)
type inputPacket struct {
Addr *Addr
Data []byte
}
type Obfuscator interface {
ObfuscatePacketConn(conn net.PacketConn) net.PacketConn
ObfuscateStreamConn(conn net.Conn) net.Conn
ObfuscateDatagramConn(conn net.Conn) net.Conn
}
type nopObfuscator struct{}
var _ Obfuscator = nopObfuscator{}
func (o nopObfuscator) ObfuscatePacketConn(conn net.PacketConn) net.PacketConn {
return conn
}
func (o nopObfuscator) ObfuscateDatagramConn(conn net.Conn) net.Conn {
return conn
}
func (o nopObfuscator) ObfuscateStreamConn(conn net.Conn) net.Conn {
return conn
}
func readStreamIDs(conn pooh.Conn) (sid, nid uint32, err error) {
sid, err = conn.Uint32()
if err != nil {
return
}
nid, err = conn.Uint32()
if err != nil {
return
}
return
}
func connIndex(conn net.Conn) uint64 {
switch local := conn.LocalAddr().(type) {
case *net.TCPAddr:
remote := conn.RemoteAddr().(*net.TCPAddr)
return endpointIndex(
pooh.IsIPv4(local.IP),
endpointTCP,
uint16(local.Port),
uint16(remote.Port),
)
case *net.UDPAddr:
remote := conn.RemoteAddr().(*net.UDPAddr)
return endpointIndex(
pooh.IsIPv4(local.IP),
endpointUDP,
uint16(local.Port),
uint16(remote.Port),
)
case *icmdp.Addr:
remote := conn.RemoteAddr().(*icmdp.Addr)
return endpointIndex(
pooh.IsIPv4(local.IP),
endpointICMDP,
local.Seq,
remote.ID, // mainly for icmdp server side to represent client port
)
default:
panic(reflect.TypeOf(local).String())
}
}
func forwardIndex(sid, nid uint32) uint64 {
return uint64(sid)<<32 + uint64(nid)
}
func readPacketIDs(p []byte) (sid, nid uint32, data []byte) {
pLen := len(p)
return binary.BigEndian.Uint32(p[pLen-4:]), binary.BigEndian.Uint32(p[pLen-8:]), data[:pLen-8]
}
func endpointIndex(ipv4 bool, typ endpointType, localPort, remotePort uint16) uint64 {
i := uint64(4)
if !ipv4 {
i = 6
}
i <<= 8
i += uint64(typ)
i <<= 16
i += uint64(localPort)
i <<= 16
i += uint64(remotePort)
return i
}