From e522811a52b9fae396d5e5bb733950a325f75631 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Tue, 22 Sep 2015 23:27:58 +0200 Subject: [PATCH] Encapsulate local discovery address in struct The XDR encoder doesn't understart slices of strings very well. It can encode and decode them, but there's no way to set limits on the length of the strings themselves (only on the length of the slice), and the generated diagrams are incorrect. This trivially works around this, while also documenting what the string actually is (a URL). --- lib/discover/local.go | 11 +- lib/discover/localpackets.go | 16 +- lib/discover/localpackets_xdr.go | 318 +++++++++++++++++++------------ 3 files changed, 212 insertions(+), 133 deletions(-) diff --git a/lib/discover/local.go b/lib/discover/local.go index 943c799fe..508128ced 100644 --- a/lib/discover/local.go +++ b/lib/discover/local.go @@ -117,7 +117,12 @@ func (c *localClient) Error() error { } func (c *localClient) announcementPkt() Announce { - addrs := c.addrList.AllAddresses() + var addrs []Address + for _, addr := range c.addrList.AllAddresses() { + addrs = append(addrs, Address{ + URL: addr, + }) + } var relays []Relay for _, relay := range c.relayStat.Relays() { @@ -198,7 +203,7 @@ func (c *localClient) registerDevice(src net.Addr, device Device) bool { var validAddresses []string for _, addr := range device.Addresses { - u, err := url.Parse(addr) + u, err := url.Parse(addr.URL) if err != nil { continue } @@ -216,7 +221,7 @@ func (c *localClient) registerDevice(src net.Addr, device Device) bool { u.Host = fmt.Sprintf("%s:%d", host, tcpAddr.Port) validAddresses = append(validAddresses, u.String()) } else { - validAddresses = append(validAddresses, addr) + validAddresses = append(validAddresses, addr.URL) } } diff --git a/lib/discover/localpackets.go b/lib/discover/localpackets.go index 9d6338d04..a24e6a1db 100644 --- a/lib/discover/localpackets.go +++ b/lib/discover/localpackets.go @@ -19,13 +19,17 @@ type Announce struct { Extra []Device // max:16 } +type Device struct { + ID []byte // max:32 + Addresses []Address // max:16 + Relays []Relay // max:16 +} + +type Address struct { + URL string // max:2083 +} + type Relay struct { URL string `json:"url"` // max:2083 Latency int32 `json:"latency"` } - -type Device struct { - ID []byte // max:32 - Addresses []string // max:16 - Relays []Relay // max:16 -} diff --git a/lib/discover/localpackets_xdr.go b/lib/discover/localpackets_xdr.go index a65efd477..dde5a3d57 100644 --- a/lib/discover/localpackets_xdr.go +++ b/lib/discover/localpackets_xdr.go @@ -113,6 +113,200 @@ func (o *Announce) DecodeXDRFrom(xr *xdr.Reader) error { /* +Device Structure: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of ID | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ ID (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Number of Addresses | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Zero or more Address Structures \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Number of Relays | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Zero or more Relay Structures \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +struct Device { + opaque ID<32>; + Address Addresses<16>; + Relay Relays<16>; +} + +*/ + +func (o Device) EncodeXDR(w io.Writer) (int, error) { + var xw = xdr.NewWriter(w) + return o.EncodeXDRInto(xw) +} + +func (o Device) MarshalXDR() ([]byte, error) { + return o.AppendXDR(make([]byte, 0, 128)) +} + +func (o Device) MustMarshalXDR() []byte { + bs, err := o.MarshalXDR() + if err != nil { + panic(err) + } + return bs +} + +func (o Device) AppendXDR(bs []byte) ([]byte, error) { + var aw = xdr.AppendWriter(bs) + var xw = xdr.NewWriter(&aw) + _, err := o.EncodeXDRInto(xw) + return []byte(aw), err +} + +func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) { + if l := len(o.ID); l > 32 { + return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) + } + xw.WriteBytes(o.ID) + if l := len(o.Addresses); l > 16 { + return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 16) + } + xw.WriteUint32(uint32(len(o.Addresses))) + for i := range o.Addresses { + _, err := o.Addresses[i].EncodeXDRInto(xw) + if err != nil { + return xw.Tot(), err + } + } + if l := len(o.Relays); l > 16 { + return xw.Tot(), xdr.ElementSizeExceeded("Relays", l, 16) + } + xw.WriteUint32(uint32(len(o.Relays))) + for i := range o.Relays { + _, err := o.Relays[i].EncodeXDRInto(xw) + if err != nil { + return xw.Tot(), err + } + } + return xw.Tot(), xw.Error() +} + +func (o *Device) DecodeXDR(r io.Reader) error { + xr := xdr.NewReader(r) + return o.DecodeXDRFrom(xr) +} + +func (o *Device) UnmarshalXDR(bs []byte) error { + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) + return o.DecodeXDRFrom(xr) +} + +func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { + o.ID = xr.ReadBytesMax(32) + _AddressesSize := int(xr.ReadUint32()) + if _AddressesSize < 0 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) + } + if _AddressesSize > 16 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) + } + o.Addresses = make([]Address, _AddressesSize) + for i := range o.Addresses { + (&o.Addresses[i]).DecodeXDRFrom(xr) + } + _RelaysSize := int(xr.ReadUint32()) + if _RelaysSize < 0 { + return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) + } + if _RelaysSize > 16 { + return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) + } + o.Relays = make([]Relay, _RelaysSize) + for i := range o.Relays { + (&o.Relays[i]).DecodeXDRFrom(xr) + } + return xr.Error() +} + +/* + +Address Structure: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of URL | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ URL (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +struct Address { + string URL<2083>; +} + +*/ + +func (o Address) EncodeXDR(w io.Writer) (int, error) { + var xw = xdr.NewWriter(w) + return o.EncodeXDRInto(xw) +} + +func (o Address) MarshalXDR() ([]byte, error) { + return o.AppendXDR(make([]byte, 0, 128)) +} + +func (o Address) MustMarshalXDR() []byte { + bs, err := o.MarshalXDR() + if err != nil { + panic(err) + } + return bs +} + +func (o Address) AppendXDR(bs []byte) ([]byte, error) { + var aw = xdr.AppendWriter(bs) + var xw = xdr.NewWriter(&aw) + _, err := o.EncodeXDRInto(xw) + return []byte(aw), err +} + +func (o Address) EncodeXDRInto(xw *xdr.Writer) (int, error) { + if l := len(o.URL); l > 2083 { + return xw.Tot(), xdr.ElementSizeExceeded("URL", l, 2083) + } + xw.WriteString(o.URL) + return xw.Tot(), xw.Error() +} + +func (o *Address) DecodeXDR(r io.Reader) error { + xr := xdr.NewReader(r) + return o.DecodeXDRFrom(xr) +} + +func (o *Address) UnmarshalXDR(bs []byte) error { + var br = bytes.NewReader(bs) + var xr = xdr.NewReader(br) + return o.DecodeXDRFrom(xr) +} + +func (o *Address) DecodeXDRFrom(xr *xdr.Reader) error { + o.URL = xr.ReadStringMax(2083) + return xr.Error() +} + +/* + Relay Structure: 0 1 2 3 @@ -184,127 +378,3 @@ func (o *Relay) DecodeXDRFrom(xr *xdr.Reader) error { o.Latency = int32(xr.ReadUint32()) return xr.Error() } - -/* - -Device Structure: - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of ID | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -/ / -\ ID (variable length) \ -/ / -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Number of Addresses | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Addresses | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -/ / -\ Addresses (variable length) \ -/ / -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Number of Relays | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -/ / -\ Zero or more Relay Structures \ -/ / -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - -struct Device { - opaque ID<32>; - string Addresses<16>; - Relay Relays<16>; -} - -*/ - -func (o Device) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) -} - -func (o Device) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) -} - -func (o Device) MustMarshalXDR() []byte { - bs, err := o.MarshalXDR() - if err != nil { - panic(err) - } - return bs -} - -func (o Device) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) { - if l := len(o.ID); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) - } - xw.WriteBytes(o.ID) - if l := len(o.Addresses); l > 16 { - return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 16) - } - xw.WriteUint32(uint32(len(o.Addresses))) - for i := range o.Addresses { - xw.WriteString(o.Addresses[i]) - } - if l := len(o.Relays); l > 16 { - return xw.Tot(), xdr.ElementSizeExceeded("Relays", l, 16) - } - xw.WriteUint32(uint32(len(o.Relays))) - for i := range o.Relays { - _, err := o.Relays[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err - } - } - return xw.Tot(), xw.Error() -} - -func (o *Device) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) -} - -func (o *Device) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) -} - -func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { - o.ID = xr.ReadBytesMax(32) - _AddressesSize := int(xr.ReadUint32()) - if _AddressesSize < 0 { - return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) - } - if _AddressesSize > 16 { - return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) - } - o.Addresses = make([]string, _AddressesSize) - for i := range o.Addresses { - o.Addresses[i] = xr.ReadString() - } - _RelaysSize := int(xr.ReadUint32()) - if _RelaysSize < 0 { - return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) - } - if _RelaysSize > 16 { - return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) - } - o.Relays = make([]Relay, _RelaysSize) - for i := range o.Relays { - (&o.Relays[i]).DecodeXDRFrom(xr) - } - return xr.Error() -}