mirror of
https://github.com/jsimonetti/rtnetlink.git
synced 2026-05-05 02:46:15 +02:00
Merge pull request #96 from jsimonetti/mdl-mpls
rtnetlink: implement MPLSNextHop encoding and decoding
This commit is contained in:
commit
9af4a03067
3
go.mod
3
go.mod
@ -5,5 +5,6 @@ go 1.12
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.3
|
||||
github.com/mdlayher/netlink v1.1.1
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7
|
||||
)
|
||||
|
||||
7
go.sum
7
go.sum
@ -4,6 +4,7 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
@ -24,6 +25,8 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjut
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -35,8 +38,8 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7 h1:Z991aAXPjz0tLnj74pVXW3eWJ5lHMIBvbRfMq4M2jHA=
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@ -65,6 +65,9 @@ const (
|
||||
IFLA_XDP_FLAGS = linux.IFLA_XDP_FLAGS
|
||||
IFLA_XDP_PROG_ID = linux.IFLA_XDP_PROG_ID
|
||||
IFLA_XDP_EXPECTED_FD = linux.IFLA_XDP_EXPECTED_FD
|
||||
LWTUNNEL_ENCAP_MPLS = linux.LWTUNNEL_ENCAP_MPLS
|
||||
MPLS_IPTUNNEL_DST = linux.MPLS_IPTUNNEL_DST
|
||||
MPLS_IPTUNNEL_TTL = linux.MPLS_IPTUNNEL_TTL
|
||||
NDA_UNSPEC = linux.NDA_UNSPEC
|
||||
NDA_DST = linux.NDA_DST
|
||||
NDA_LLADDR = linux.NDA_LLADDR
|
||||
@ -72,6 +75,8 @@ const (
|
||||
NDA_IFINDEX = linux.NDA_IFINDEX
|
||||
RTA_UNSPEC = linux.RTA_UNSPEC
|
||||
RTA_DST = linux.RTA_DST
|
||||
RTA_ENCAP = linux.RTA_ENCAP
|
||||
RTA_ENCAP_TYPE = linux.RTA_ENCAP_TYPE
|
||||
RTA_PREFSRC = linux.RTA_PREFSRC
|
||||
RTA_GATEWAY = linux.RTA_GATEWAY
|
||||
RTA_OIF = linux.RTA_OIF
|
||||
|
||||
@ -61,6 +61,9 @@ const (
|
||||
IFLA_XDP_FLAGS = 0x3
|
||||
IFLA_XDP_PROG_ID = 0x4
|
||||
IFLA_XDP_EXPECTED_FD = 0x8
|
||||
LWTUNNEL_ENCAP_MPLS = 0x1
|
||||
MPLS_IPTUNNEL_DST = 0x1
|
||||
MPLS_IPTUNNEL_TTL = 0x2
|
||||
NDA_UNSPEC = 0x0
|
||||
NDA_DST = 0x1
|
||||
NDA_LLADDR = 0x2
|
||||
@ -68,6 +71,8 @@ const (
|
||||
NDA_IFINDEX = 0x8
|
||||
RTA_UNSPEC = 0x0
|
||||
RTA_DST = 0x1
|
||||
RTA_ENCAP = 0x16
|
||||
RTA_ENCAP_TYPE = 0x15
|
||||
RTA_PREFSRC = 0x7
|
||||
RTA_GATEWAY = 0x5
|
||||
RTA_OIF = 0x4
|
||||
|
||||
126
route.go
126
route.go
@ -1,6 +1,7 @@
|
||||
package rtnetlink
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"unsafe"
|
||||
@ -348,8 +349,9 @@ type RTNextHop struct {
|
||||
|
||||
// NextHop wraps struct rtnexthop to provide access to nested attributes
|
||||
type NextHop struct {
|
||||
Hop RTNextHop // a rtnexthop struct
|
||||
Gateway net.IP // that struct's nested Gateway attribute
|
||||
Hop RTNextHop // a rtnexthop struct
|
||||
Gateway net.IP // that struct's nested Gateway attribute
|
||||
MPLS []MPLSNextHop // Any MPLS next hops for a route.
|
||||
}
|
||||
|
||||
func (a *RouteAttributes) encodeMultipath() ([]byte, error) {
|
||||
@ -359,11 +361,18 @@ func (a *RouteAttributes) encodeMultipath() ([]byte, error) {
|
||||
// compute the length of each (rtnexthop, attributes) pair.
|
||||
ae := netlink.NewAttributeEncoder()
|
||||
|
||||
if a.Gateway != nil {
|
||||
if nh.Gateway != nil {
|
||||
// TODO(mdlayher): more validation.
|
||||
ae.Bytes(unix.RTA_GATEWAY, nh.Gateway)
|
||||
}
|
||||
|
||||
if len(nh.MPLS) > 0 {
|
||||
// TODO(mdlayher): validation over different encapsulation types,
|
||||
// and ensure that only one can be set.
|
||||
ae.Uint16(unix.RTA_ENCAP_TYPE, unix.LWTUNNEL_ENCAP_MPLS)
|
||||
ae.Nested(unix.RTA_ENCAP, nh.encodeEncap)
|
||||
}
|
||||
|
||||
ab, err := ae.Encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -417,16 +426,26 @@ func (a *RouteAttributes) parseMultipath(b []byte) error {
|
||||
return mpp.Err()
|
||||
}
|
||||
|
||||
// rtnexthop payload is at least one nested attribute RTA_GATEWAY
|
||||
// possibly others?
|
||||
// decode decodes netlink attribute values into a NextHop.
|
||||
func (nh *NextHop) decode(ad *netlink.AttributeDecoder) error {
|
||||
if ad == nil {
|
||||
// Invalid decoder, do nothing.
|
||||
return nil
|
||||
}
|
||||
|
||||
// If encapsulation is present, we won't know how to deal with it until we
|
||||
// identify the right type and then later parse the nested attribute bytes.
|
||||
var (
|
||||
encapType uint16
|
||||
encapBuf []byte
|
||||
)
|
||||
|
||||
for ad.Next() {
|
||||
switch ad.Type() {
|
||||
case unix.RTA_ENCAP:
|
||||
encapBuf = ad.Bytes()
|
||||
case unix.RTA_ENCAP_TYPE:
|
||||
encapType = ad.Uint16()
|
||||
case unix.RTA_GATEWAY:
|
||||
l := len(ad.Bytes())
|
||||
if l != 4 && l != 16 {
|
||||
@ -437,6 +456,103 @@ func (nh *NextHop) decode(ad *netlink.AttributeDecoder) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := ad.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if encapType != 0 && encapBuf != nil {
|
||||
// Found encapsulation, start decoding it from the buffer.
|
||||
return nh.decodeEncap(encapType, encapBuf)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// An MPLSNextHop is a route next hop using MPLS encapsulation.
|
||||
type MPLSNextHop struct {
|
||||
Label int
|
||||
TrafficClass int
|
||||
BottomOfStack bool
|
||||
TTL uint8
|
||||
}
|
||||
|
||||
// TODO(mdlayher): MPLSNextHop TTL vs MPLS_IPTUNNEL_TTL. What's the difference?
|
||||
|
||||
// encodeEncap encodes netlink attribute values related to encapsulation from
|
||||
// a NextHop.
|
||||
func (nh *NextHop) encodeEncap(ae *netlink.AttributeEncoder) error {
|
||||
// TODO: this only handles MPLS encapsulation as that is all we support.
|
||||
|
||||
// Allocate enough space for an MPLS label stack.
|
||||
var (
|
||||
i int
|
||||
b = make([]byte, 4*len(nh.MPLS))
|
||||
)
|
||||
|
||||
for _, mnh := range nh.MPLS {
|
||||
// Pack the following:
|
||||
// - label: 20 bits
|
||||
// - traffic class: 3 bits
|
||||
// - bottom-of-stack: 1 bit
|
||||
// - TTL: 8 bits
|
||||
binary.BigEndian.PutUint32(b[i:i+4], uint32(mnh.Label)<<12)
|
||||
|
||||
b[i+2] |= byte(mnh.TrafficClass) << 1
|
||||
|
||||
if mnh.BottomOfStack {
|
||||
b[i+2] |= 1
|
||||
}
|
||||
|
||||
b[i+3] = mnh.TTL
|
||||
|
||||
// Advance in the buffer to begin storing the next label.
|
||||
i += 4
|
||||
}
|
||||
|
||||
// Finally store the output bytes.
|
||||
ae.Bytes(unix.MPLS_IPTUNNEL_DST, b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeEncap decodes netlink attribute values related to encapsulation into a
|
||||
// NextHop.
|
||||
func (nh *NextHop) decodeEncap(typ uint16, b []byte) error {
|
||||
if typ != unix.LWTUNNEL_ENCAP_MPLS {
|
||||
// TODO: handle other encapsulation types as needed.
|
||||
return nil
|
||||
}
|
||||
|
||||
// MPLS labels are stored as big endian bytes.
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for ad.Next() {
|
||||
switch ad.Type() {
|
||||
case unix.MPLS_IPTUNNEL_DST:
|
||||
// Every 4 bytes stores another MPLS label, so make sure the stored
|
||||
// bytes are divisible by exactly 4.
|
||||
b := ad.Bytes()
|
||||
if len(b)%4 != 0 {
|
||||
return errInvalidRouteMessageAttr
|
||||
}
|
||||
|
||||
for i := 0; i < len(b); i += 4 {
|
||||
n := binary.BigEndian.Uint32(b[i : i+4])
|
||||
|
||||
// For reference, see:
|
||||
// https://en.wikipedia.org/wiki/Multiprotocol_Label_Switching#Operation
|
||||
nh.MPLS = append(nh.MPLS, MPLSNextHop{
|
||||
Label: int(n) >> 12,
|
||||
TrafficClass: int(n & 0xe00 >> 9),
|
||||
BottomOfStack: n&0x100 != 0,
|
||||
TTL: uint8(n & 0xff),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ad.Err()
|
||||
}
|
||||
|
||||
|
||||
@ -204,6 +204,96 @@ func TestRouteMessageMarshalUnmarshalBinary(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteMessageMarshalRoundTrip(t *testing.T) {
|
||||
skipBigEndian(t)
|
||||
|
||||
// The above tests begin with unmarshaling raw bytes and are more
|
||||
// comprehensive, but due to the complexity of nested route message
|
||||
// attributes and structures, it has become rather difficult to maintain
|
||||
// over time. These tests will focus on a subset of that functionality to
|
||||
// ensure that marshaling and unmarshaling perform symmetrical operations
|
||||
// given a proper Go type as input, rather than raw bytes.
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
m *RouteMessage
|
||||
}{
|
||||
{
|
||||
name: "multipath MPLS",
|
||||
m: &RouteMessage{
|
||||
Attributes: RouteAttributes{
|
||||
Multipath: []NextHop{
|
||||
{
|
||||
Hop: RTNextHop{
|
||||
Length: 48,
|
||||
IfIndex: 1,
|
||||
},
|
||||
Gateway: net.IPv4(10, 0, 0, 2),
|
||||
MPLS: []MPLSNextHop{{
|
||||
Label: 1,
|
||||
TrafficClass: 1,
|
||||
BottomOfStack: true,
|
||||
TTL: 1,
|
||||
}},
|
||||
},
|
||||
{
|
||||
Hop: RTNextHop{
|
||||
Length: 52,
|
||||
IfIndex: 2,
|
||||
},
|
||||
Gateway: net.IPv4(10, 0, 0, 3),
|
||||
MPLS: []MPLSNextHop{
|
||||
{
|
||||
Label: 1,
|
||||
TrafficClass: 1,
|
||||
TTL: 1,
|
||||
},
|
||||
{
|
||||
Label: 2,
|
||||
TrafficClass: 2,
|
||||
BottomOfStack: true,
|
||||
TTL: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// First do a marshaling and unmarshaling round trip to ensure
|
||||
// the inputs and outputs are identical.
|
||||
b1, err := tt.m.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal test message: %v", err)
|
||||
}
|
||||
|
||||
var m RouteMessage
|
||||
if err := m.UnmarshalBinary(b1); err != nil {
|
||||
t.Fatalf("failed to unmarshal: %v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tt.m, &m); diff != "" {
|
||||
t.Fatalf("unexpected RouteMessage after round-trip (-want +got):\n%s", diff)
|
||||
}
|
||||
|
||||
// Then compare the results of the first marshaled bytes against
|
||||
// the newly marshaled bytes.
|
||||
b2, err := m.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal parsed message: %v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(b1, b2); diff != "" {
|
||||
t.Fatalf("unexpected final raw byte output (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteMessageUnmarshalBinaryErrors(t *testing.T) {
|
||||
skipBigEndian(t)
|
||||
|
||||
|
||||
BIN
testdata/corpus/015234b16d15fc9a8d0087ebcbabf42ed76c0812-38
vendored
Normal file
BIN
testdata/corpus/015234b16d15fc9a8d0087ebcbabf42ed76c0812-38
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/049f49dc2b6c163d5faf1ded2c621fd1a28c9747-38
vendored
Normal file
BIN
testdata/corpus/049f49dc2b6c163d5faf1ded2c621fd1a28c9747-38
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/082652416315336b5ba00681f7a743ccbbcbdd71-39
vendored
Normal file
BIN
testdata/corpus/082652416315336b5ba00681f7a743ccbbcbdd71-39
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/1820dbf6107ca7b5c9a0467c4d9303de5d983334-36
vendored
Normal file
BIN
testdata/corpus/1820dbf6107ca7b5c9a0467c4d9303de5d983334-36
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/22050367926486cb43405d88b376404852959eb0-37
vendored
Normal file
BIN
testdata/corpus/22050367926486cb43405d88b376404852959eb0-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/2b10146eb2804173932f2f25df49dcde84bd5422-39
vendored
Normal file
BIN
testdata/corpus/2b10146eb2804173932f2f25df49dcde84bd5422-39
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/2bf9c12550df885e9b2f0066bdaa24d693ba358b-38
vendored
Normal file
BIN
testdata/corpus/2bf9c12550df885e9b2f0066bdaa24d693ba358b-38
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/2e9520c3b8fd2b783473a53ce62ed06a80684085-39
vendored
Normal file
BIN
testdata/corpus/2e9520c3b8fd2b783473a53ce62ed06a80684085-39
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/3dc09ec53e9c6aaee007fa6d1bc15e94fffbc71d-40
vendored
Normal file
BIN
testdata/corpus/3dc09ec53e9c6aaee007fa6d1bc15e94fffbc71d-40
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/5171ca7f61ac7a502d3d95b7939f6484604d76a4-36
vendored
Normal file
BIN
testdata/corpus/5171ca7f61ac7a502d3d95b7939f6484604d76a4-36
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/579d7e8d1b834c1665bf8d262f3db3ef0d15f768-41
vendored
Normal file
BIN
testdata/corpus/579d7e8d1b834c1665bf8d262f3db3ef0d15f768-41
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/57c84d561021cf943fbe5f8e16fb4779a0f28565-39
vendored
Normal file
BIN
testdata/corpus/57c84d561021cf943fbe5f8e16fb4779a0f28565-39
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/62b920726253e633e85f93860b81a7cbb9a9d2d2-44
vendored
Normal file
BIN
testdata/corpus/62b920726253e633e85f93860b81a7cbb9a9d2d2-44
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/6e7731a90348ac8f9a9b796a36b0d0b69626c649-40
vendored
Normal file
BIN
testdata/corpus/6e7731a90348ac8f9a9b796a36b0d0b69626c649-40
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/793b71b44e38d3dd13bac21a7122660593abe93e-40
vendored
Normal file
BIN
testdata/corpus/793b71b44e38d3dd13bac21a7122660593abe93e-40
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/7c9c703ad40808292786df199ad7b19c9e62ef41-37
vendored
Normal file
BIN
testdata/corpus/7c9c703ad40808292786df199ad7b19c9e62ef41-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/7d3d6e6c965f90001b7c070c3b0a13b6eaf7a7b2-38
vendored
Normal file
BIN
testdata/corpus/7d3d6e6c965f90001b7c070c3b0a13b6eaf7a7b2-38
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/897184d5d21106fd90c7fb106e3b6bc2a82cc747-42
vendored
Normal file
BIN
testdata/corpus/897184d5d21106fd90c7fb106e3b6bc2a82cc747-42
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/8b3a1a36b36ef5bc3b65aec5ac39b6147bdd7827-36
vendored
Normal file
BIN
testdata/corpus/8b3a1a36b36ef5bc3b65aec5ac39b6147bdd7827-36
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/8c17bb9286605de46b6821387afce1ec5deb05eb-43
vendored
Normal file
BIN
testdata/corpus/8c17bb9286605de46b6821387afce1ec5deb05eb-43
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/8f433f0523d2446a2d89543e110eb2e4d9c32574-45
vendored
Normal file
BIN
testdata/corpus/8f433f0523d2446a2d89543e110eb2e4d9c32574-45
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/91be8558028512ff8b8347a5cb2f1fc3d638d2a5-37
vendored
Normal file
BIN
testdata/corpus/91be8558028512ff8b8347a5cb2f1fc3d638d2a5-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/92d4fec98c3d3bfa639ee7b8eef2cc053ce28371-40
vendored
Normal file
BIN
testdata/corpus/92d4fec98c3d3bfa639ee7b8eef2cc053ce28371-40
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/9995561d583953138ccfd0e503281ceb1ce41303-43
vendored
Normal file
BIN
testdata/corpus/9995561d583953138ccfd0e503281ceb1ce41303-43
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/a19f5e2491ee591b9b56a677774959ba11cc3904-41
vendored
Normal file
BIN
testdata/corpus/a19f5e2491ee591b9b56a677774959ba11cc3904-41
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/ae8252330686905fb5ca04487bcce1495d049916-39
vendored
Normal file
BIN
testdata/corpus/ae8252330686905fb5ca04487bcce1495d049916-39
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/ba740bcd54cbcd72e1ee257b491e12b0393688f7-37
vendored
Normal file
BIN
testdata/corpus/ba740bcd54cbcd72e1ee257b491e12b0393688f7-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/bf2de846441c88778157887d19dd31dcfec04275-41
vendored
Normal file
BIN
testdata/corpus/bf2de846441c88778157887d19dd31dcfec04275-41
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/c786db5f13f18bdf03cdf0a0960633d80228f1ba-45
vendored
Normal file
BIN
testdata/corpus/c786db5f13f18bdf03cdf0a0960633d80228f1ba-45
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/c9fa1541d79005ea684b524b509412ac99bf0922-37
vendored
Normal file
BIN
testdata/corpus/c9fa1541d79005ea684b524b509412ac99bf0922-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/ce8e84d605fbd5e56c4228047ebb0df33d419f9a-44
vendored
Normal file
BIN
testdata/corpus/ce8e84d605fbd5e56c4228047ebb0df33d419f9a-44
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/d90dbd3bc30144653fa216693e1da2371b75e35c-37
vendored
Normal file
BIN
testdata/corpus/d90dbd3bc30144653fa216693e1da2371b75e35c-37
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/e9f13f887905c098392e3e07bb1c1e0dec1adb72-42
vendored
Normal file
BIN
testdata/corpus/e9f13f887905c098392e3e07bb1c1e0dec1adb72-42
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/f1a6fc940fa8898d872272a80983757b5c0d7022-43
vendored
Normal file
BIN
testdata/corpus/f1a6fc940fa8898d872272a80983757b5c0d7022-43
vendored
Normal file
Binary file not shown.
BIN
testdata/corpus/fe9fabd89fb613484e6ba2c4cf7126497ec94718-36
vendored
Normal file
BIN
testdata/corpus/fe9fabd89fb613484e6ba2c4cf7126497ec94718-36
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user