• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 16529627948

25 Jul 2025 07:05PM UTC coverage: 67.245% (+0.04%) from 67.206%
16529627948

Pull #9455

github

web-flow
Merge ac9ed1e9c into 839370946
Pull Request #9455: discovery+lnwire: add support for DNS host name in NodeAnnouncement msg

131 of 179 new or added lines in 6 files covered. (73.18%)

59 existing lines in 16 files now uncovered.

135645 of 201717 relevant lines covered (67.25%)

21649.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.47
/graph/db/addr.go
1
package graphdb
2

3
import (
4
        "encoding/binary"
5
        "errors"
6
        "fmt"
7
        "io"
8
        "net"
9

10
        "github.com/lightningnetwork/lnd/lnwire"
11
        "github.com/lightningnetwork/lnd/tor"
12
)
13

14
// addressType specifies the network protocol and version that should be used
15
// when connecting to a node at a particular address.
16
type addressType uint8
17

18
const (
19
        // tcp4Addr denotes an IPv4 TCP address.
20
        tcp4Addr addressType = 0
21

22
        // tcp6Addr denotes an IPv6 TCP address.
23
        tcp6Addr addressType = 1
24

25
        // v2OnionAddr denotes a version 2 Tor onion service address.
26
        v2OnionAddr addressType = 2
27

28
        // v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
29
        v3OnionAddr addressType = 3
30

31
        // opaqueAddrs denotes an address (or a set of addresses) that LND was
32
        // not able to parse since LND is not yet aware of the address type.
33
        opaqueAddrs addressType = 4
34

35
        // dnsAddr denotes a DNS hostname address.
36
        dnsAddr addressType = 5
37
)
38

39
// encodeTCPAddr serializes a TCP address into its compact raw bytes
40
// representation.
41
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
2,124✔
42
        var (
2,124✔
43
                addrType byte
2,124✔
44
                ip       []byte
2,124✔
45
        )
2,124✔
46

2,124✔
47
        if addr.IP.To4() != nil {
3,858✔
48
                addrType = byte(tcp4Addr)
1,734✔
49
                ip = addr.IP.To4()
1,734✔
50
        } else {
2,127✔
51
                addrType = byte(tcp6Addr)
393✔
52
                ip = addr.IP.To16()
393✔
53
        }
393✔
54

55
        if ip == nil {
2,128✔
56
                return fmt.Errorf("unable to encode IP %v", addr.IP)
4✔
57
        }
4✔
58

59
        if _, err := w.Write([]byte{addrType}); err != nil {
2,120✔
60
                return err
×
61
        }
×
62

63
        if _, err := w.Write(ip); err != nil {
2,120✔
64
                return err
×
65
        }
×
66

67
        var port [2]byte
2,120✔
68
        byteOrder.PutUint16(port[:], uint16(addr.Port))
2,120✔
69
        if _, err := w.Write(port[:]); err != nil {
2,120✔
70
                return err
×
71
        }
×
72

73
        return nil
2,120✔
74
}
75

76
// encodeOnionAddr serializes an onion address into its compact raw bytes
77
// representation.
78
func encodeOnionAddr(w io.Writer, addr *tor.OnionAddr) error {
212✔
79
        var suffixIndex int
212✔
80
        hostLen := len(addr.OnionService)
212✔
81
        switch hostLen {
212✔
82
        case tor.V2Len:
106✔
83
                if _, err := w.Write([]byte{byte(v2OnionAddr)}); err != nil {
106✔
84
                        return err
×
85
                }
×
86
                suffixIndex = tor.V2Len - tor.OnionSuffixLen
106✔
87
        case tor.V3Len:
108✔
88
                if _, err := w.Write([]byte{byte(v3OnionAddr)}); err != nil {
108✔
89
                        return err
×
90
                }
×
91
                suffixIndex = tor.V3Len - tor.OnionSuffixLen
108✔
92
        default:
1✔
93
                return errors.New("unknown onion service length")
1✔
94
        }
95

96
        suffix := addr.OnionService[suffixIndex:]
211✔
97
        if suffix != tor.OnionSuffix {
212✔
98
                return fmt.Errorf("invalid suffix \"%v\"", suffix)
1✔
99
        }
1✔
100

101
        host, err := tor.Base32Encoding.DecodeString(
210✔
102
                addr.OnionService[:suffixIndex],
210✔
103
        )
210✔
104
        if err != nil {
211✔
105
                return err
1✔
106
        }
1✔
107

108
        // Sanity check the decoded length.
109
        switch {
209✔
110
        case hostLen == tor.V2Len && len(host) != tor.V2DecodedLen:
×
111
                return fmt.Errorf("onion service %v decoded to invalid host %x",
×
112
                        addr.OnionService, host)
×
113

114
        case hostLen == tor.V3Len && len(host) != tor.V3DecodedLen:
×
115
                return fmt.Errorf("onion service %v decoded to invalid host %x",
×
116
                        addr.OnionService, host)
×
117
        }
118

119
        if _, err := w.Write(host); err != nil {
209✔
120
                return err
×
121
        }
×
122

123
        var port [2]byte
209✔
124
        byteOrder.PutUint16(port[:], uint16(addr.Port))
209✔
125
        if _, err := w.Write(port[:]); err != nil {
209✔
126
                return err
×
127
        }
×
128

129
        return nil
209✔
130
}
131

132
// encodeDNSAddr serializes a DNS address into its compact raw bytes
133
// representation.
134
func encodeDNSAddr(w io.Writer, addr *lnwire.DNSAddr) error {
3✔
135
        // Validate DNS address.
3✔
136
        _, err := lnwire.NewDNSAddr(addr.Hostname, addr.Port)
3✔
137
        if err != nil {
3✔
NEW
138
                return err
×
NEW
139
        }
×
140

141
        // Write the address type.
142
        if _, err := w.Write([]byte{byte(dnsAddr)}); err != nil {
3✔
NEW
143
                return err
×
NEW
144
        }
×
145

146
        // Write the length of the hostname.
147
        hostnameLen := byte(len(addr.Hostname))
3✔
148
        if _, err := w.Write([]byte{hostnameLen}); err != nil {
3✔
NEW
149
                return err
×
NEW
150
        }
×
151

152
        // Write the hostname bytes.
153
        if _, err := w.Write([]byte(addr.Hostname)); err != nil {
3✔
NEW
154
                return err
×
NEW
155
        }
×
156

157
        // Write the port in big-endian order.
158
        var port [2]byte
3✔
159
        binary.BigEndian.PutUint16(port[:], uint16(addr.Port))
3✔
160
        if _, err := w.Write(port[:]); err != nil {
3✔
NEW
161
                return err
×
NEW
162
        }
×
163

164
        return nil
3✔
165
}
166

167
// encodeOpaqueAddrs serializes the lnwire.OpaqueAddrs type to a raw set of
168
// bytes that we will persist.
169
func encodeOpaqueAddrs(w io.Writer, addr *lnwire.OpaqueAddrs) error {
2✔
170
        // Write the type byte.
2✔
171
        if _, err := w.Write([]byte{byte(opaqueAddrs)}); err != nil {
2✔
172
                return err
×
173
        }
×
174

175
        // Write the length of the payload.
176
        var l [2]byte
2✔
177
        binary.BigEndian.PutUint16(l[:], uint16(len(addr.Payload)))
2✔
178
        if _, err := w.Write(l[:]); err != nil {
2✔
179
                return err
×
180
        }
×
181

182
        // Write the payload.
183
        _, err := w.Write(addr.Payload)
2✔
184

2✔
185
        return err
2✔
186
}
187

188
// DeserializeAddr reads the serialized raw representation of an address and
189
// deserializes it into the actual address. This allows us to avoid address
190
// resolution within the channeldb package.
191
func DeserializeAddr(r io.Reader) (net.Addr, error) {
11,297✔
192
        var addrType [1]byte
11,297✔
193
        if _, err := r.Read(addrType[:]); err != nil {
11,297✔
194
                return nil, err
×
195
        }
×
196

197
        var address net.Addr
11,297✔
198
        switch addressType(addrType[0]) {
11,297✔
199
        case tcp4Addr:
4,526✔
200
                var ip [4]byte
4,526✔
201
                if _, err := r.Read(ip[:]); err != nil {
4,526✔
202
                        return nil, err
×
203
                }
×
204

205
                var port [2]byte
4,526✔
206
                if _, err := r.Read(port[:]); err != nil {
4,526✔
207
                        return nil, err
×
208
                }
×
209

210
                address = &net.TCPAddr{
4,526✔
211
                        IP:   net.IP(ip[:]),
4,526✔
212
                        Port: int(binary.BigEndian.Uint16(port[:])),
4,526✔
213
                }
4,526✔
214

215
        case tcp6Addr:
6,563✔
216
                var ip [16]byte
6,563✔
217
                if _, err := r.Read(ip[:]); err != nil {
6,563✔
218
                        return nil, err
×
219
                }
×
220

221
                var port [2]byte
6,563✔
222
                if _, err := r.Read(port[:]); err != nil {
6,563✔
223
                        return nil, err
×
224
                }
×
225

226
                address = &net.TCPAddr{
6,563✔
227
                        IP:   net.IP(ip[:]),
6,563✔
228
                        Port: int(binary.BigEndian.Uint16(port[:])),
6,563✔
229
                }
6,563✔
230

231
        case v2OnionAddr:
107✔
232
                var h [tor.V2DecodedLen]byte
107✔
233
                if _, err := r.Read(h[:]); err != nil {
107✔
234
                        return nil, err
×
235
                }
×
236

237
                var p [2]byte
107✔
238
                if _, err := r.Read(p[:]); err != nil {
107✔
239
                        return nil, err
×
240
                }
×
241

242
                onionService := tor.Base32Encoding.EncodeToString(h[:])
107✔
243
                onionService += tor.OnionSuffix
107✔
244
                port := int(binary.BigEndian.Uint16(p[:]))
107✔
245

107✔
246
                address = &tor.OnionAddr{
107✔
247
                        OnionService: onionService,
107✔
248
                        Port:         port,
107✔
249
                }
107✔
250

251
        case v3OnionAddr:
107✔
252
                var h [tor.V3DecodedLen]byte
107✔
253
                if _, err := r.Read(h[:]); err != nil {
107✔
254
                        return nil, err
×
255
                }
×
256

257
                var p [2]byte
107✔
258
                if _, err := r.Read(p[:]); err != nil {
107✔
259
                        return nil, err
×
260
                }
×
261

262
                onionService := tor.Base32Encoding.EncodeToString(h[:])
107✔
263
                onionService += tor.OnionSuffix
107✔
264
                port := int(binary.BigEndian.Uint16(p[:]))
107✔
265

107✔
266
                address = &tor.OnionAddr{
107✔
267
                        OnionService: onionService,
107✔
268
                        Port:         port,
107✔
269
                }
107✔
270

271
        case opaqueAddrs:
3✔
272
                // Read the length of the payload.
3✔
273
                var l [2]byte
3✔
274
                if _, err := r.Read(l[:]); err != nil {
3✔
275
                        return nil, err
×
276
                }
×
277

278
                // Read the payload.
279
                payload := make([]byte, binary.BigEndian.Uint16(l[:]))
3✔
280
                if _, err := r.Read(payload); err != nil {
3✔
281
                        return nil, err
×
282
                }
×
283

284
                address = &lnwire.OpaqueAddrs{
3✔
285
                        Payload: payload,
3✔
286
                }
3✔
287

288
        case dnsAddr:
3✔
289
                var hostnameLen byte
3✔
290
                err := binary.Read(r, binary.BigEndian, &hostnameLen)
3✔
291
                if err != nil {
3✔
NEW
292
                        return nil, err
×
NEW
293
                }
×
294

295
                hostname := make([]byte, hostnameLen)
3✔
296
                if _, err := r.Read(hostname); err != nil {
3✔
NEW
297
                        return nil, err
×
NEW
298
                }
×
299

300
                var port [2]byte
3✔
301
                n, err := r.Read(port[:])
3✔
302
                if err != nil {
3✔
NEW
303
                        return nil, err
×
NEW
304
                }
×
305
                if n != 2 {
3✔
NEW
306
                        return nil, fmt.Errorf("expected to read 2 bytes for "+
×
NEW
307
                                "port, but got %d bytes", n)
×
NEW
308
                }
×
309

310
                dnsAddr, err := lnwire.NewDNSAddr(
3✔
311
                        string(hostname), int(binary.BigEndian.Uint16(port[:])),
3✔
312
                )
3✔
313
                if err != nil {
3✔
NEW
314
                        return nil, err
×
NEW
315
                }
×
316

317
                address = dnsAddr
3✔
318

319
        default:
×
320
                return nil, ErrUnknownAddressType
×
321
        }
322

323
        return address, nil
11,297✔
324
}
325

326
// SerializeAddr serializes an address into its raw bytes representation so that
327
// it can be deserialized without requiring address resolution.
328
func SerializeAddr(w io.Writer, address net.Addr) error {
2,336✔
329
        switch addr := address.(type) {
2,336✔
330
        case *net.TCPAddr:
2,124✔
331
                return encodeTCPAddr(w, addr)
2,124✔
332
        case *tor.OnionAddr:
212✔
333
                return encodeOnionAddr(w, addr)
212✔
334
        case *lnwire.DNSAddr:
3✔
335
                return encodeDNSAddr(w, addr)
3✔
336
        case *lnwire.OpaqueAddrs:
2✔
337
                return encodeOpaqueAddrs(w, addr)
2✔
338
        default:
1✔
339
                return ErrUnknownAddressType
1✔
340
        }
341
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc