-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcid.go
78 lines (64 loc) · 1.43 KB
/
cid.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
package utp_go
import (
"encoding/hex"
"fmt"
"hash"
"net"
"sync"
"golang.org/x/crypto/sha3"
)
var hasherPool = sync.Pool{
New: func() interface{} {
return sha3.New256()
},
}
// ConnectionPeer is an interface representing a remote peer.
type ConnectionPeer interface {
Hash() string
}
// SocketAddr is a simple implementation of the ConnectionPeer interface using net.UDPAddr.
type UdpPeer struct {
addr *net.UDPAddr
}
func NewUdpPeer(addr *net.UDPAddr) *UdpPeer {
return &UdpPeer{addr: addr}
}
func (p *UdpPeer) Hash() string {
return p.addr.String()
}
func (p *UdpPeer) String() string {
return p.addr.String()
}
type TcpPeer struct {
addr *net.TCPAddr
}
func (p *TcpPeer) Hash() string {
return p.addr.String()
}
func (p *TcpPeer) String() string {
return p.addr.String()
}
// ConnectionId represents a connection identifier with send and receive IDs and a peer.
type ConnectionId struct {
Send uint16
Recv uint16
Peer ConnectionPeer
hash string
}
func (id *ConnectionId) Hash() string {
if id.hash == "" {
str := fmt.Sprintf("%d:%d:%v", id.Send, id.Recv, id.Peer.Hash())
hasher := hasherPool.Get().(hash.Hash)
defer func() {
hasher.Reset()
hasherPool.Put(hasher)
}()
hasher.Write([]byte(str))
bytes := hasher.Sum(nil)[:20]
id.hash = hex.EncodeToString(bytes)
}
return id.hash
}
func (id *ConnectionId) String() string {
return fmt.Sprintf("send_id: %d recv_id:%d peer:%v", id.Send, id.Recv, id.Peer)
}