Skip to content

Commit

Permalink
feat(peers): peer representation and marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianLusina committed Jul 15, 2022
1 parent fb80785 commit 11c735a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
38 changes: 38 additions & 0 deletions pkg/peers/peer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package peers

import (
"encoding/binary"
"fmt"
"net"
"strconv"
)

// Peer encodes connection information for a peer
type Peer struct {
IP net.IP
Port uint16
}

// Unmarshal parses peer IP addresses and ports from a buffer
func Unmarshal(peersBin []byte) ([]Peer, error) {
// 4 for IP, 2 for port
const peerSize = 6
numPeers := len(peersBin) / peerSize
if len(peersBin)%peerSize != 0 {
err := fmt.Errorf("Received malformed peers")
return nil, err
}

peers := make([]Peer, numPeers)
for i := 0; i < numPeers; i++ {
offset := i * peerSize
peers[i].IP = net.IP(peersBin[offset : offset+4])
peers[i].Port = binary.BigEndian.Uint16(peersBin[offset+4 : offset+6])
}

return peers, nil
}

func (p Peer) String() string {
return net.JoinHostPort(p.IP.String(), strconv.Itoa(int(p.Port)))
}
55 changes: 55 additions & 0 deletions pkg/peers/peer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package peers

import (
"net"
"testing"

"github.com/stretchr/testify/assert"
)

func TestUnmarshall(t *testing.T) {
tests := map[string]struct {
input string
output []Peer
fails bool
}{
"correctly parses peers": {
input: string([]byte{127, 0, 0, 1, 0x00, 0x50, 1, 1, 1, 1, 0x01, 0xbb}),
output: []Peer{
{IP: net.IP{127, 0, 0, 1}, Port: 80},
{IP: net.IP{1, 1, 1, 1}, Port: 443},
},
},
"not enough bytes in peers": {
input: string([]byte{127, 0, 0, 1, 0x00}),
output: nil,
fails: true,
},
}

for _, test := range tests {
peers, err := Unmarshal([]byte(test.input))
if test.fails {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
}
assert.Equal(t, test.output, peers)
}
}

func TestString(t *testing.T) {
tests := []struct {
input Peer
output string
}{
{
input: Peer{IP: net.IP{127, 0, 0, 1}, Port: 8080},
output: "127.0.0.1:8080",
},
}
for _, test := range tests {
s := test.input.String()
assert.Equal(t, test.output, s)
}
}

0 comments on commit 11c735a

Please sign in to comment.