Skip to content

Commit a93c76b

Browse files
committed
transport: replace net.IP with netip.Addr
Fixes #274
1 parent 88fc8ef commit a93c76b

9 files changed

+59
-44
lines changed

frame/buffer_read.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package frame
33
import (
44
"fmt"
55
"log"
6+
"net/netip"
67
)
78

89
// All the read functions call readByte or readInto as they would want to read a single byte or copy a slice of bytes.
@@ -160,7 +161,9 @@ func (b *Buffer) ReadInet() Inet {
160161
log.Printf("unknown ip length")
161162
}
162163
}
163-
return Inet{IP: b.readCopy(int(n)), Port: b.ReadInt()}
164+
165+
ip, _ := netip.AddrFromSlice(b.readCopy(int(n)))
166+
return Inet{IP: ip, Port: b.ReadInt()}
164167
}
165168

166169
func (b *Buffer) ReadString() string {

frame/buffer_write.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,14 @@ func (b *Buffer) WriteValue(v Value) {
119119
}
120120

121121
func (b *Buffer) WriteInet(v Inet) {
122+
addr := v.IP.AsSlice()
122123
if Debug {
123-
if l := len(v.IP); l != 4 && l != 16 {
124-
log.Printf("unknown IP length")
124+
if len(addr) != 4 && len(addr) != 16 {
125+
log.Printf("unknown ip length")
125126
}
126127
}
127-
b.WriteByte(Byte(len(v.IP)))
128-
b.Write(v.IP)
128+
b.WriteByte(Byte(len(addr)))
129+
b.Write(addr)
129130
b.WriteInt(v.Port)
130131
}
131132

frame/cqlvalue.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"encoding/binary"
55
"fmt"
66
"math"
7-
"net"
7+
"net/netip"
88
"unicode"
99
"unicode/utf8"
1010
)
@@ -153,16 +153,17 @@ func (c CqlValue) AsText() (string, error) {
153153
return string(c.Value), nil
154154
}
155155

156-
func (c CqlValue) AsIP() (net.IP, error) {
156+
func (c CqlValue) AsIP() (netip.Addr, error) {
157157
if c.Type.ID != InetID {
158-
return nil, fmt.Errorf("%v is not of Inet type", c)
158+
return netip.Addr{}, fmt.Errorf("%v is not of Inet type", c)
159159
}
160160

161-
if len(c.Value) != 4 && len(c.Value) != 16 {
162-
return nil, fmt.Errorf("invalid ip length")
161+
ret, ok := netip.AddrFromSlice(c.Value)
162+
if !ok {
163+
return netip.Addr{}, fmt.Errorf("invalid ip length")
163164
}
164165

165-
return c.Value, nil
166+
return ret, nil
166167
}
167168

168169
func (c CqlValue) AsFloat32() (float32, error) {
@@ -414,17 +415,15 @@ func CqlFromTimeUUID(b [16]byte) (CqlValue, error) {
414415
return c, nil
415416
}
416417

417-
func CqlFromIP(ip net.IP) (CqlValue, error) {
418-
if len(ip) != 4 || len(ip) != 16 {
419-
return CqlValue{}, fmt.Errorf("invalid ip address")
418+
func CqlFromIP(ip netip.Addr) (CqlValue, error) {
419+
if ip.BitLen() == 0 {
420+
return CqlValue{}, fmt.Errorf("zero addr is not supported")
420421
}
421422

422-
c := CqlValue{
423+
return CqlValue{
423424
Type: &Option{ID: InetID},
424-
Value: make(Bytes, len(ip)),
425-
}
426-
copy(c.Value, ip)
427-
return c, nil
425+
Value: ip.AsSlice(),
426+
}, nil
428427
}
429428

430429
func CqlFromFloat32(v float32) CqlValue {

frame/cqlvalue_fuzz_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package frame
33
import (
44
"math"
55
"net"
6+
"net/netip"
67
"testing"
78

89
"github.com/google/go-cmp/cmp"
@@ -142,12 +143,17 @@ func FuzzCqlValueText(f *testing.F) {
142143
}
143144

144145
func FuzzCqlValueIP(f *testing.F) {
145-
testCases := [][]byte{{1, 2, 3}, net.IP{127, 0, 0, 1}, net.IP{127, 0, 0, 1}.To16()}
146+
testCases := [][]byte{net.IP{127, 0, 0, 1}, net.IP{127, 0, 0, 1}.To16()}
146147
for _, tc := range testCases {
147148
f.Add(tc)
148149
}
149150
f.Fuzz(func(t *testing.T, data []byte) {
150-
in, err := CqlFromIP(data)
151+
ip, ok := netip.AddrFromSlice(data)
152+
if !ok {
153+
t.Skip()
154+
}
155+
156+
in, err := CqlFromIP(ip)
151157
if err != nil {
152158
// We skip tests with incorrect CqlValue.
153159
t.Skip()

frame/cqlvalue_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package frame
22

33
import (
44
"math"
5-
"net"
5+
"net/netip"
66
"testing"
77

88
"github.com/google/go-cmp/cmp"
@@ -509,7 +509,7 @@ func TestCqlValueAsIP(t *testing.T) {
509509
name string
510510
content CqlValue
511511
valid bool
512-
expected net.IP
512+
expected netip.Addr
513513
}{
514514
{
515515
name: "wrong length",
@@ -530,19 +530,19 @@ func TestCqlValueAsIP(t *testing.T) {
530530
name: "valid v4",
531531
content: CqlValue{
532532
Type: &Option{ID: InetID},
533-
Value: Bytes(net.IP{127, 0, 0, 1}),
533+
Value: Bytes{127, 0, 0, 1},
534534
},
535535
valid: true,
536-
expected: net.IP{127, 0, 0, 1},
536+
expected: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
537537
},
538538
{
539539
name: "valid v6",
540540
content: CqlValue{
541541
Type: &Option{ID: InetID},
542-
Value: Bytes(net.IP{127, 0, 0, 1}.To16()),
542+
Value: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1},
543543
},
544544
valid: true,
545-
expected: net.IP{127, 0, 0, 1}.To16(),
545+
expected: netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1}),
546546
},
547547
}
548548

@@ -557,8 +557,8 @@ func TestCqlValueAsIP(t *testing.T) {
557557
}
558558
return
559559
}
560-
if diff := cmp.Diff(v, tc.expected); diff != "" {
561-
t.Fatalf(diff)
560+
if v != tc.expected {
561+
t.Fatalf("expected %v, got %v", tc.expected, v)
562562
}
563563
})
564564
}

frame/response/event_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package response
22

33
import (
4+
"net/netip"
45
"testing"
56

67
"github.com/scylladb/scylla-go-driver/frame"
@@ -21,15 +22,15 @@ func TestStatusChangeEvent(t *testing.T) { // nolint:dupl // Tests are different
2122
var b frame.Buffer
2223
b.WriteString("UP")
2324
b.WriteInet(frame.Inet{
24-
IP: []byte{127, 0, 0, 1},
25+
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
2526
Port: 9042,
2627
})
2728
return b.Bytes()
2829
}(),
2930
expected: StatusChange{
3031
Status: "UP",
3132
Address: frame.Inet{
32-
IP: []byte{127, 0, 0, 1},
33+
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
3334
Port: 9042,
3435
},
3536
},
@@ -42,8 +43,8 @@ func TestStatusChangeEvent(t *testing.T) { // nolint:dupl // Tests are different
4243
var buf frame.Buffer
4344
buf.Write(tc.content)
4445
a := ParseStatusChange(&buf)
45-
if diff := cmp.Diff(*a, tc.expected); diff != "" {
46-
t.Fatal(diff)
46+
if *a != tc.expected {
47+
t.Fatalf("expected %v, got %v", tc.expected, *a)
4748
}
4849
})
4950
}
@@ -62,15 +63,15 @@ func TestTopologyChangeEvent(t *testing.T) { //nolint:dupl // Tests are differen
6263
var b frame.Buffer
6364
b.WriteString("NEW_NODE")
6465
b.WriteInet(frame.Inet{
65-
IP: []byte{127, 0, 0, 1},
66+
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
6667
Port: 9042,
6768
})
6869
return b.Bytes()
6970
}(),
7071
expected: TopologyChange{
7172
Change: "NEW_NODE",
7273
Address: frame.Inet{
73-
IP: []byte{127, 0, 0, 1},
74+
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
7475
Port: 9042,
7576
},
7677
},
@@ -83,8 +84,8 @@ func TestTopologyChangeEvent(t *testing.T) { //nolint:dupl // Tests are differen
8384
var buf frame.Buffer
8485
buf.Write(tc.content)
8586
a := ParseTopologyChange(&buf)
86-
if diff := cmp.Diff(*a, tc.expected); diff != "" {
87-
t.Fatal(diff)
87+
if *a != tc.expected {
88+
t.Fatalf("expected %v, got %v", tc.expected, *a)
8889
}
8990
})
9091
}

frame/types.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package frame
22

33
import (
44
"errors"
5-
"net"
5+
"net/netip"
66
)
77

88
// Generic types from CQL binary protocol.
@@ -40,13 +40,13 @@ func (v Value) Clone() Value {
4040

4141
// https://github.com/apache/cassandra/blob/adcff3f630c0d07d1ba33bf23fcb11a6db1b9af1/doc/native_protocol_v4.spec#L241-L245
4242
type Inet struct {
43-
IP Bytes
43+
IP netip.Addr
4444
Port Int
4545
}
4646

4747
// String only takes care of IP part of the address.
4848
func (i Inet) String() string {
49-
return net.IP(i.IP).String()
49+
return i.IP.String()
5050
}
5151

5252
// https://github.com/apache/cassandra/blob/adcff3f630c0d07d1ba33bf23fcb11a6db1b9af1/doc/native_protocol_v4.spec#L183-L201

transport/cluster.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"log"
77
"net"
8+
"net/netip"
89
"sort"
910
"strconv"
1011
"strings"
@@ -320,20 +321,23 @@ func (c *Cluster) parseNodeFromRow(r frame.Row) (*Node, error) {
320321
}
321322
// Possible IP addresses starts from addrIndex in both system.local and system.peers queries.
322323
// They are grouped with decreasing priority.
323-
var addr net.IP
324+
var addr netip.Addr
324325
for i := addrIndex; i < len(r); i++ {
325326
addr, err = r[i].AsIP()
326327
if err == nil && !addr.IsUnspecified() {
327328
break
328329
} else if err == nil && addr.IsUnspecified() {
329330
host, _, err := net.SplitHostPort(c.control.conn.RemoteAddr().String())
330331
if err == nil {
331-
addr = net.ParseIP(host)
332+
addr, err = netip.ParseAddr(host)
333+
if err != nil {
334+
addr = netip.AddrFrom4([4]byte{0, 0, 0, 0})
335+
}
332336
break
333337
}
334338
}
335339
}
336-
if addr == nil || addr.IsUnspecified() {
340+
if addr.IsUnspecified() {
337341
return nil, fmt.Errorf("all addr columns conatin invalid IP")
338342
}
339343
return &Node{

transport/cluster_integration_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package transport
55
import (
66
"context"
77
"fmt"
8+
"net/netip"
89
"os/signal"
910
"syscall"
1011
"testing"
@@ -40,7 +41,7 @@ func TestClusterIntegration(t *testing.T) {
4041
defer cancel()
4142

4243
addr := frame.Inet{
43-
IP: []byte{192, 168, 100, 100},
44+
IP: netip.MustParseAddr(TestHost),
4445
Port: 9042,
4546
}
4647

0 commit comments

Comments
 (0)