/
address.go
117 lines (104 loc) · 2.55 KB
/
address.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
117
/*
* Copyright 2020 PeerGum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package core
import (
"crypto/rand"
"fmt"
"log"
)
const (
AddressSize = 4
DistMax = 1<<15 - 1
)
type Address [AddressSize]uint16
type Distance uint16
var (
AddressNone = Address{0}
BroadcastAddress = Address{65535}
)
//
// --- Distances
//
func (address Address) Distance(address2 Address) Distance {
var d int16 = DistMax
//var vLow, v2Low PeerAddress
for i, v := range address {
v2 := address2[i]
//for j := range *peerAddress {
// Abs returns the absolute value of x.
di := Abs(Abs(int16(v)-32767) - Abs(int16(v2)-32767))
//if di > DistMax/2 {
// di = DistMax - di
//}
if di < d {
d = di
}
//}
}
if d > 0 {
WORMHOLE_TEST:
for i, v := range address {
for j, v2 := range address2 {
if v == v2 && i != j {
d = 0
break WORMHOLE_TEST
}
}
}
}
return Distance(d)
}
func Abs(x int16) int16 {
if x < 0 {
return -x
}
return x
}
func (address Address) isBroadcast() bool {
return address == BroadcastAddress
}
//
// --- Utils
//
func generateAddress() (address Address) {
for i := range address {
for ; address[i] == 0 || address[i] == 65535; {
addr := make([]byte, 2)
for ; uint16(addr[0])<<8+uint16(addr[1]) == 0 ||
uint16(addr[0])<<8+uint16(addr[1]) == 65535; {
if _, err := rand.Read(addr); err != nil {
log.Fatal("Can't generate address")
}
}
address[i] = uint16(addr[0])<<8 + uint16(addr[1])
}
}
return address
}
//
// --- Representation
//
func (address Address) String() (value string) {
for i, a := range address {
if i > 0 {
value += ":"
}
if a != 0 {
value += fmt.Sprintf("%x", a)
}
}
return value
}