Skip to content

Commit 0fdd983

Browse files
various bug fixes
1 parent e726cd0 commit 0fdd983

File tree

5 files changed

+78
-46
lines changed

5 files changed

+78
-46
lines changed

exec/ws/config.example.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
[connection]
22
# remote websocket endpoint
3-
remote = "ws://127.0.0.1:8081"
3+
remote = "ws://127.0.0.1:8080"
44
# name for this instance
55
name = "debug-client"
6-
# key used for verify this instance
7-
key = "keyusedforhmac"
86
# retry times before give up
97
retry = 10
108
# the key used in SHA256-HMAC authentication

exec/ws/main.go

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -186,19 +186,21 @@ func main() {
186186
WriteBufferSize: 1048576,
187187
}
188188

189-
h := hmac.New(sha256.New, []byte(config.Conn.Key))
190-
identifier := fmt.Sprintf("%s.%x.%x", config.Conn.Name, time.Now().Unix(), rand.Uint64())
191-
h.Write([]byte(identifier))
192-
header := http.Header{}
193-
header.Set("X-Identifier", identifier)
194-
header.Set("X-Signature", hex.EncodeToString(h.Sum(nil)))
189+
rand.Seed(time.Now().UnixNano())
195190

196191
retryCount := uint32(0)
197192

198193
for {
194+
identifier := fmt.Sprintf("%s.%x.%x", config.Conn.Name, time.Now().Unix(), rand.Uint64())
195+
header := http.Header{}
196+
header.Set("X-Identifier", identifier)
197+
h := hmac.New(sha256.New, []byte(config.Conn.Key))
198+
h.Write([]byte(identifier))
199+
header.Set("X-Signature", hex.EncodeToString(h.Sum(nil)))
200+
199201
conn, _, err := dialer.Dial(config.Conn.Remote, header)
200-
stopper := make(chan struct{})
201-
pChan := make(chan Response, 16)
202+
var stopper chan struct{}
203+
var pChan chan Response
202204
if err != nil {
203205
if retryCount < config.Conn.Retry {
204206
retryCount++
@@ -209,6 +211,9 @@ func main() {
209211
}
210212
}
211213

214+
stopper = make(chan struct{})
215+
pChan = make(chan Response, 16)
216+
212217
go func() {
213218
tick := time.NewTicker(time.Second * 10)
214219

@@ -244,6 +249,8 @@ func main() {
244249
return nil
245250
})
246251

252+
log.Printf("Connection to %s established.\n", config.Conn.Remote)
253+
247254
NextMsg:
248255
for {
249256
t, r, err := conn.NextReader()
@@ -275,7 +282,7 @@ func main() {
275282
continue
276283
}
277284
length := binary.BigEndian.Uint32(headBuffer)
278-
if length > 1048576 {
285+
if length > 16*1024*1024 {
279286
log.Printf("Invalid length: %d\n", length)
280287
continue
281288
}
@@ -309,12 +316,13 @@ func main() {
309316
}
310317

311318
CleanUp:
312-
pChan = nil
313-
stopper <- struct{}{}
314-
_ = conn.Close()
315-
icmp.FinishICMPManager()
319+
if conn != nil {
320+
stopper <- struct{}{}
321+
_ = conn.Close()
322+
}
323+
icmp.GetICMPManager().Flush()
316324

317-
time.Sleep(time.Second * 10)
325+
time.Sleep(time.Second)
318326
}
319327

320328
}

exec/ws/workflow.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ X-Signature: hex-encoded HMAC-SHA256 for X-Identifier
99

1010
2. Server does a series of check to the connection:
1111

12-
- Server should check the signature is valid, otherwise the connection should be
12+
- Server SHALL check the signature is valid, otherwise the connection SHALL be
1313
closed immediately.
1414

15-
- Upon check pass, server should check the time span from the timestamp in
15+
- Upon check pass, server SHALL check the time span from the timestamp in
1616
Identifier to server current time is within a specific range (say span A),
17-
otherwise the connection should be closed immediately.
17+
otherwise the connection SHALL be closed immediately.
1818

19-
- Then the nonce should be recorded and connection within such a span A using the
20-
same nonce should be closed immediately.
19+
- Then the nonce SHALL be recorded and connection within such a span A using the
20+
same nonce SHALL be closed immediately.
2121

2222
3. Perform connection upgrade and establish websocket connection
2323

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1
1919
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
2020
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
2121
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
22+
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
2223
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
2324
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
2425
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -29,6 +30,7 @@ github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr
2930
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
3031
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
3132
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
33+
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
3234
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
3335
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
3436
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -42,6 +44,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
4244
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
4345
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4446
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
47+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
4548
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4649
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
4750
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
@@ -52,11 +55,13 @@ github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
5255
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
5356
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
5457
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
58+
github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8=
5559
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
5660
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
5761
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
5862
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5963
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
64+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
6065
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6166
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
6267
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
@@ -71,6 +76,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
7176
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
7277
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
7378
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
79+
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
7480
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7581
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
7682
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -79,9 +85,11 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
7985
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8086
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
8187
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
88+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
8289
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
8390
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
8491
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
92+
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
8593
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
8694
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
8795
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=

tool/icmp/icmp.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
"math/rand"
1010
"net"
1111
"sync"
12+
"sync/atomic"
1213
"time"
14+
"unsafe"
1315
)
1416

1517
// An ICMPRequest represents an ICMPRequest issued by ping or trace for listener
@@ -34,16 +36,20 @@ func (r *ICMPRequest) SetTimeout(duration time.Duration) {
3436
r.Deadline = r.IssueTime.Add(duration)
3537
}
3638

37-
func (r ICMPRequest) Passed(time time.Time) bool {
39+
func (r *ICMPRequest) Passed(time time.Time) bool {
3840
return r.Deadline.Before(time)
3941
}
4042

41-
func (r ICMPRequest) Deliver(response Response) bool {
43+
func (r *ICMPRequest) Deliver(response Response) bool {
44+
if r.delivery == nil {
45+
return false
46+
}
47+
4248
if response == nil {
4349
r.delivery <- &Result{
4450
Code: 256,
4551
}
46-
close(r.delivery)
52+
r.delivery = nil
4753
return true
4854
}
4955
ID, TargetIP := response.GetIdentifier()
@@ -60,7 +66,7 @@ func (r ICMPRequest) Deliver(response Response) bool {
6066
Code: Code,
6167
}
6268
}
63-
close(r.delivery)
69+
r.delivery = nil
6470
return true
6571
}
6672
return false
@@ -82,11 +88,11 @@ type ICMPResponse struct {
8288
Code int
8389
}
8490

85-
func (I ICMPResponse) GetIdentifier() (int, net.IP) {
91+
func (I *ICMPResponse) GetIdentifier() (int, net.IP) {
8692
return I.ID, I.TargetIP
8793
}
8894

89-
func (I ICMPResponse) GetInformation() (net.IP, time.Time, int) {
95+
func (I *ICMPResponse) GetInformation() (net.IP, time.Time, int) {
9096
return I.AddrIP, I.Received, I.Code
9197
}
9298

@@ -118,12 +124,10 @@ type ICMPManager struct {
118124
// which send other Protocol message(e.g. TCP, UDP) but expect ICMP reply
119125
// messages.
120126
extListener map[int]chan *RawResponse
121-
// counter will fill the sequence field of the request (precisely 16bits)
127+
// counter will fill the sequence field of the request (use low 16bits)
122128
// to identify packet. it will be increased for each call and can hold at
123129
// most 65536 concurrent pending requests.
124-
counter uint16
125-
// l is the mutex to make counter increment thread safe.
126-
l sync.Mutex
130+
counter uint32
127131
// context to send the manager stop message
128132
ctx context.Context
129133
// function to call to stop the manager
@@ -138,7 +142,7 @@ type ICMPManager struct {
138142
var manager *ICMPManager
139143
var once sync.Once
140144

141-
// listen to ICMP socket to receive packet
145+
// ICMPv4Receiver listen to ICMP socket to receive packet
142146
func ICMPv4Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan *ICMPResponse,
143147
rawResponse chan *RawResponse, ctx context.Context) {
144148
select {
@@ -151,7 +155,11 @@ func ICMPv4Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan
151155
// return
152156
//}
153157
// wait `wait` to receive some body
154-
if err := conn.SetDeadline(time.Now().Add(wait)); err != nil {
158+
var deadline time.Time
159+
if wait != 0 {
160+
deadline = time.Now().Add(wait)
161+
}
162+
if err := conn.SetDeadline(deadline); err != nil {
155163
return
156164
}
157165
readBytes := make([]byte, 1500) // max MTU
@@ -238,7 +246,7 @@ func ICMPv4Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan
238246
}
239247
}
240248

241-
// listen to ICMPv6 socket to receive packet
249+
// ICMPv6Receiver listen to ICMPv6 socket to receive packet
242250
func ICMPv6Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan *ICMPResponse,
243251
rawResponse chan *RawResponse, ctx context.Context) {
244252
select {
@@ -251,7 +259,11 @@ func ICMPv6Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan
251259
// return
252260
//}
253261
// wait `wait` to receive some body
254-
if err := conn.SetDeadline(time.Now().Add(wait)); err != nil {
262+
var deadline time.Time
263+
if wait != 0 {
264+
deadline = time.Now().Add(wait)
265+
}
266+
if err := conn.SetDeadline(deadline); err != nil {
255267
return
256268
}
257269
readBytes := make([]byte, 1500) // max MTU
@@ -338,8 +350,9 @@ func ICMPv6Receiver(conn *icmp.PacketConn, wait time.Duration, icmpResponse chan
338350
}
339351
}
340352

341-
// return ICMPManager to caller. As listening to ICMP will receive all ICMP
342-
// packet, there will be only one manager in the whole process.
353+
// GetICMPManager return ICMPManager to caller.
354+
// As listening to ICMP will receive all ICMP packet,
355+
// there will be only one manager in the whole process.
343356
func GetICMPManager() *ICMPManager {
344357
once.Do(func() {
345358
ctx, cancel := context.WithCancel(context.Background())
@@ -363,15 +376,15 @@ func GetICMPManager() *ICMPManager {
363376
panic(fmt.Sprintf("Can't listen to ICMPv6: %s", err))
364377
}
365378
manager.pConn6 = conn6
366-
go ICMPv4Receiver(conn4, 1000*time.Millisecond, result4, raw4, ctx)
367-
go ICMPv6Receiver(conn6, 1000*time.Millisecond, result6, raw6, ctx)
379+
go ICMPv4Receiver(conn4, 0, result4, raw4, ctx)
380+
go ICMPv6Receiver(conn6, 0, result6, raw6, ctx)
368381
go manager.icmpDispatcher(result4, result6)
369382
go manager.rawDispatcher(raw4, raw6)
370383
// warm-up
371384
addr, _ := net.ResolveIPAddr("", "127.0.0.1")
372-
manager.Issue(addr, 100, time.Second)
385+
<-manager.Issue(addr, 100, time.Second)
373386
addr, _ = net.ResolveIPAddr("", "::1")
374-
manager.Issue(addr, 100, time.Second)
387+
<-manager.Issue(addr, 100, time.Second)
375388
})
376389
return manager
377390
}
@@ -389,10 +402,7 @@ func (mgr *ICMPManager) Issue(ip net.Addr, ttl int, timeout time.Duration) (deli
389402
}
390403
dest = ipAddr.IP.To16()
391404

392-
mgr.l.Lock()
393-
count := mgr.counter
394-
mgr.counter++
395-
mgr.l.Unlock()
405+
count := (atomic.AddUint32(&mgr.counter, 1) - 1) & 0xffff
396406

397407
id := rand.Intn(1 << 16)
398408
var msg []byte
@@ -500,6 +510,14 @@ func (mgr *ICMPManager) rawDispatcher(v4, v6 chan *RawResponse) {
500510
}
501511
}
502512

513+
func (mgr *ICMPManager) Flush() {
514+
queue := NewCMap(32)
515+
queue = (*ConMapRequest)(atomic.SwapPointer((*unsafe.Pointer)((unsafe.Pointer)(&mgr.queue)), unsafe.Pointer(queue)))
516+
for t := range mgr.queue.IterBuffered() {
517+
t.Val.Deliver(nil)
518+
}
519+
}
520+
503521
func (mgr *ICMPManager) Finish() {
504522
mgr.cancel()
505523
}

0 commit comments

Comments
 (0)