1515package peersharing
1616
1717import (
18+ "encoding/binary"
1819 "fmt"
20+ "net"
1921
2022 "github.com/blinklabs-io/gouroboros/cbor"
2123 "github.com/blinklabs-io/gouroboros/protocol"
@@ -66,21 +68,10 @@ func NewMsgShareRequest(amount uint8) *MsgShareRequest {
6668
6769type MsgSharePeers struct {
6870 protocol.MessageBase
69- // TODO: parse peer addresses
70- /*
71- peerAddress = [0, word32, portNumber]
72- ; ipv6 + portNumber
73- / [1, word32, word32, word32, word32, flowInfo, scopeId, portNumber]
74-
75- portNumber = word16
76-
77- flowInfo = word32
78- scopeId = word32
79- */
80- PeerAddresses []interface {}
71+ PeerAddresses []PeerAddress
8172}
8273
83- func NewMsgSharePeers (peerAddresses []interface {} ) * MsgSharePeers {
74+ func NewMsgSharePeers (peerAddresses []PeerAddress ) * MsgSharePeers {
8475 m := & MsgSharePeers {
8576 MessageBase : protocol.MessageBase {
8677 MessageType : MessageTypeSharePeers ,
@@ -102,3 +93,85 @@ func NewMsgDone() *MsgDone {
10293 }
10394 return m
10495}
96+
97+ type PeerAddress struct {
98+ IP net.IP
99+ Port uint16
100+ }
101+
102+ func (p * PeerAddress ) UnmarshalCBOR (cborData []byte ) error {
103+ peerType , err := cbor .DecodeIdFromList (cborData )
104+ if err != nil {
105+ return err
106+ }
107+ switch peerType {
108+ case 0 :
109+ // IPv4
110+ tmpPeer := struct {
111+ cbor.StructAsArray
112+ PeerType int
113+ Address uint32
114+ Port uint16
115+ }{}
116+ if _ , err := cbor .Decode (cborData , & tmpPeer ); err != nil {
117+ return err
118+ }
119+ p .IP = make (net.IP , net .IPv4len )
120+ binary .LittleEndian .PutUint32 (p .IP , tmpPeer .Address )
121+ p .Port = tmpPeer .Port
122+ case 1 :
123+ // IPv6
124+ cborListLen , err := cbor .ListLength (cborData )
125+ if err != nil {
126+ return err
127+ }
128+ if cborListLen == 8 {
129+ // V11-12
130+ tmpPeer := struct {
131+ cbor.StructAsArray
132+ PeerType int
133+ Address1 uint32
134+ Address2 uint32
135+ Address3 uint32
136+ Address4 uint32
137+ FlowInfo uint32 // ignored
138+ ScopeId uint32 // ignored
139+ Port uint16
140+ }{}
141+ if _ , err := cbor .Decode (cborData , & tmpPeer ); err != nil {
142+ return err
143+ }
144+ p .IP = make (net.IP , net .IPv6len )
145+ binary .LittleEndian .PutUint32 (p .IP [0 :], tmpPeer .Address1 )
146+ binary .LittleEndian .PutUint32 (p .IP [4 :], tmpPeer .Address2 )
147+ binary .LittleEndian .PutUint32 (p .IP [8 :], tmpPeer .Address3 )
148+ binary .LittleEndian .PutUint32 (p .IP [12 :], tmpPeer .Address4 )
149+ p .Port = tmpPeer .Port
150+ } else if cborListLen == 6 {
151+ // V13+
152+ tmpPeer := struct {
153+ cbor.StructAsArray
154+ PeerType int
155+ Address1 uint32
156+ Address2 uint32
157+ Address3 uint32
158+ Address4 uint32
159+ Port uint16
160+ }{}
161+ if _ , err := cbor .Decode (cborData , & tmpPeer ); err != nil {
162+ return err
163+ }
164+ p .IP = make (net.IP , net .IPv6len )
165+ binary .LittleEndian .PutUint32 (p .IP [0 :], tmpPeer .Address1 )
166+ binary .LittleEndian .PutUint32 (p .IP [4 :], tmpPeer .Address2 )
167+ binary .LittleEndian .PutUint32 (p .IP [8 :], tmpPeer .Address3 )
168+ binary .LittleEndian .PutUint32 (p .IP [12 :], tmpPeer .Address4 )
169+ p .Port = tmpPeer .Port
170+ } else {
171+ return fmt .Errorf ("invalid peer address length: %d" , cborListLen )
172+ }
173+ default :
174+ return fmt .Errorf ("unknown peer type: %d\n " , peerType )
175+ }
176+ return nil
177+ }
0 commit comments