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

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

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

55.68
/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

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

3✔
44
        if addr.IP.To4() != nil {
6✔
45
                addrType = byte(tcp4Addr)
3✔
46
                ip = addr.IP.To4()
3✔
47
        } else {
6✔
48
                addrType = byte(tcp6Addr)
3✔
49
                ip = addr.IP.To16()
3✔
50
        }
3✔
51

52
        if ip == nil {
3✔
UNCOV
53
                return fmt.Errorf("unable to encode IP %v", addr.IP)
×
UNCOV
54
        }
×
55

56
        if _, err := w.Write([]byte{addrType}); err != nil {
3✔
57
                return err
×
58
        }
×
59

60
        if _, err := w.Write(ip); err != nil {
3✔
61
                return err
×
62
        }
×
63

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

70
        return nil
3✔
71
}
72

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

93
        suffix := addr.OnionService[suffixIndex:]
3✔
94
        if suffix != tor.OnionSuffix {
3✔
UNCOV
95
                return fmt.Errorf("invalid suffix \"%v\"", suffix)
×
UNCOV
96
        }
×
97

98
        host, err := tor.Base32Encoding.DecodeString(
3✔
99
                addr.OnionService[:suffixIndex],
3✔
100
        )
3✔
101
        if err != nil {
3✔
UNCOV
102
                return err
×
UNCOV
103
        }
×
104

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

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

116
        if _, err := w.Write(host); err != nil {
3✔
117
                return err
×
118
        }
×
119

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

126
        return nil
3✔
127
}
128

129
// encodeOpaqueAddrs serializes the lnwire.OpaqueAddrs type to a raw set of
130
// bytes that we will persist.
UNCOV
131
func encodeOpaqueAddrs(w io.Writer, addr *lnwire.OpaqueAddrs) error {
×
UNCOV
132
        // Write the type byte.
×
UNCOV
133
        if _, err := w.Write([]byte{byte(opaqueAddrs)}); err != nil {
×
134
                return err
×
135
        }
×
136

137
        // Write the length of the payload.
UNCOV
138
        var l [2]byte
×
UNCOV
139
        binary.BigEndian.PutUint16(l[:], uint16(len(addr.Payload)))
×
UNCOV
140
        if _, err := w.Write(l[:]); err != nil {
×
141
                return err
×
142
        }
×
143

144
        // Write the payload.
UNCOV
145
        _, err := w.Write(addr.Payload)
×
UNCOV
146

×
UNCOV
147
        return err
×
148
}
149

150
// DeserializeAddr reads the serialized raw representation of an address and
151
// deserializes it into the actual address. This allows us to avoid address
152
// resolution within the channeldb package.
153
func DeserializeAddr(r io.Reader) (net.Addr, error) {
3✔
154
        var addrType [1]byte
3✔
155
        if _, err := r.Read(addrType[:]); err != nil {
3✔
156
                return nil, err
×
157
        }
×
158

159
        var address net.Addr
3✔
160
        switch addressType(addrType[0]) {
3✔
161
        case tcp4Addr:
3✔
162
                var ip [4]byte
3✔
163
                if _, err := r.Read(ip[:]); err != nil {
3✔
164
                        return nil, err
×
165
                }
×
166

167
                var port [2]byte
3✔
168
                if _, err := r.Read(port[:]); err != nil {
3✔
169
                        return nil, err
×
170
                }
×
171

172
                address = &net.TCPAddr{
3✔
173
                        IP:   net.IP(ip[:]),
3✔
174
                        Port: int(binary.BigEndian.Uint16(port[:])),
3✔
175
                }
3✔
176

177
        case tcp6Addr:
3✔
178
                var ip [16]byte
3✔
179
                if _, err := r.Read(ip[:]); err != nil {
3✔
180
                        return nil, err
×
181
                }
×
182

183
                var port [2]byte
3✔
184
                if _, err := r.Read(port[:]); err != nil {
3✔
185
                        return nil, err
×
186
                }
×
187

188
                address = &net.TCPAddr{
3✔
189
                        IP:   net.IP(ip[:]),
3✔
190
                        Port: int(binary.BigEndian.Uint16(port[:])),
3✔
191
                }
3✔
192

193
        case v2OnionAddr:
3✔
194
                var h [tor.V2DecodedLen]byte
3✔
195
                if _, err := r.Read(h[:]); err != nil {
3✔
196
                        return nil, err
×
197
                }
×
198

199
                var p [2]byte
3✔
200
                if _, err := r.Read(p[:]); err != nil {
3✔
201
                        return nil, err
×
202
                }
×
203

204
                onionService := tor.Base32Encoding.EncodeToString(h[:])
3✔
205
                onionService += tor.OnionSuffix
3✔
206
                port := int(binary.BigEndian.Uint16(p[:]))
3✔
207

3✔
208
                address = &tor.OnionAddr{
3✔
209
                        OnionService: onionService,
3✔
210
                        Port:         port,
3✔
211
                }
3✔
212

213
        case v3OnionAddr:
3✔
214
                var h [tor.V3DecodedLen]byte
3✔
215
                if _, err := r.Read(h[:]); err != nil {
3✔
216
                        return nil, err
×
217
                }
×
218

219
                var p [2]byte
3✔
220
                if _, err := r.Read(p[:]); err != nil {
3✔
221
                        return nil, err
×
222
                }
×
223

224
                onionService := tor.Base32Encoding.EncodeToString(h[:])
3✔
225
                onionService += tor.OnionSuffix
3✔
226
                port := int(binary.BigEndian.Uint16(p[:]))
3✔
227

3✔
228
                address = &tor.OnionAddr{
3✔
229
                        OnionService: onionService,
3✔
230
                        Port:         port,
3✔
231
                }
3✔
232

UNCOV
233
        case opaqueAddrs:
×
UNCOV
234
                // Read the length of the payload.
×
UNCOV
235
                var l [2]byte
×
UNCOV
236
                if _, err := r.Read(l[:]); err != nil {
×
237
                        return nil, err
×
238
                }
×
239

240
                // Read the payload.
UNCOV
241
                payload := make([]byte, binary.BigEndian.Uint16(l[:]))
×
UNCOV
242
                if _, err := r.Read(payload); err != nil {
×
243
                        return nil, err
×
244
                }
×
245

UNCOV
246
                address = &lnwire.OpaqueAddrs{
×
UNCOV
247
                        Payload: payload,
×
UNCOV
248
                }
×
249

250
        default:
×
251
                return nil, ErrUnknownAddressType
×
252
        }
253

254
        return address, nil
3✔
255
}
256

257
// SerializeAddr serializes an address into its raw bytes representation so that
258
// it can be deserialized without requiring address resolution.
259
func SerializeAddr(w io.Writer, address net.Addr) error {
3✔
260
        switch addr := address.(type) {
3✔
261
        case *net.TCPAddr:
3✔
262
                return encodeTCPAddr(w, addr)
3✔
263
        case *tor.OnionAddr:
3✔
264
                return encodeOnionAddr(w, addr)
3✔
UNCOV
265
        case *lnwire.OpaqueAddrs:
×
UNCOV
266
                return encodeOpaqueAddrs(w, addr)
×
UNCOV
267
        default:
×
UNCOV
268
                return ErrUnknownAddressType
×
269
        }
270
}
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