From 452b133a53c34dd713ba881ab9d8ebe3ffeac553 Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Wed, 30 Nov 2022 14:53:14 -0800 Subject: [PATCH] Revert commits that break public API Reverts 9f2193cff5787215d13b4a02288482e2f7da74fe^..30bbb28ace5af9a34aa4835acca352a2ee9aa21f --- .github/generate-authors.sh | 23 +- .github/install-hooks.sh | 6 +- .github/lint-commit-message.sh | 4 +- .../lint-disallowed-functions-in-library.sh | 29 +- .github/lint-filename.sh | 8 +- ...int-no-trailing-newline-in-log-messages.sh | 24 +- AUTHORS.txt | 2 - connctx/connctx_test.go | 8 +- examples/vnet-udpproxy/main.go | 8 +- go.mod | 2 +- go.sum | 12 +- net.go | 415 ------------------ packetio/buffer.go | 38 +- packetio/buffer_test.go | 6 +- packetio/hardlimit.go | 3 +- packetio/no_hardlimit.go | 2 +- replaydetector/replaydetector.go | 2 +- replaydetector/replaydetector_test.go | 2 +- stdnet/net.go | 164 ------- test/bridge.go | 2 +- test/bridge_test.go | 2 +- test/util.go | 8 +- utils/xor/xor_arm64.go | 1 - vnet/README.md | 74 ++-- vnet/chunk.go | 6 +- vnet/chunk_test.go | 6 +- vnet/conn.go | 227 ++++------ vnet/conn_test.go | 5 +- vnet/delay_filter_test.go | 26 +- vnet/interface.go | 40 ++ vnet/loss_filter_test.go | 27 +- vnet/nat.go | 11 +- vnet/nat_test.go | 24 +- vnet/net.go | 376 +++++++++------- stdnet/net_test.go => vnet/net_native_test.go | 71 ++- vnet/net_test.go | 281 +++++------- vnet/resolver.go | 4 +- vnet/router.go | 36 +- vnet/router_test.go | 162 +++---- vnet/stress_test.go | 14 +- vnet/tbf.go | 2 +- vnet/tbf_test.go | 6 +- vnet/udpproxy.go | 35 +- vnet/udpproxy_direct_test.go | 22 +- vnet/udpproxy_test.go | 50 +-- 45 files changed, 787 insertions(+), 1489 deletions(-) delete mode 100644 net.go delete mode 100644 stdnet/net.go create mode 100644 vnet/interface.go rename stdnet/net_test.go => vnet/net_native_test.go (83%) diff --git a/.github/generate-authors.sh b/.github/generate-authors.sh index 6152721..182e4f5 100755 --- a/.github/generate-authors.sh +++ b/.github/generate-authors.sh @@ -12,10 +12,10 @@ set -e SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) -GIT_WORKDIR=${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)} -AUTHORS_PATH="${GIT_WORKDIR}/AUTHORS.txt" +AUTHORS_PATH="$GITHUB_WORKSPACE/AUTHORS.txt" -if [ -f ${SCRIPT_PATH}/.ci.conf ]; then +if [ -f ${SCRIPT_PATH}/.ci.conf ] +then . ${SCRIPT_PATH}/.ci.conf fi @@ -31,7 +31,8 @@ EXCLUDED_CONTRIBUTORS+=('John R. Bradley' 'renovate[bot]' 'Renovate Bot' 'Pion B CONTRIBUTORS=() shouldBeIncluded () { - for i in "${EXCLUDED_CONTRIBUTORS[@]}"; do + for i in "${EXCLUDED_CONTRIBUTORS[@]}" + do if [[ $1 =~ "$i" ]]; then return 1 fi @@ -41,23 +42,25 @@ shouldBeIncluded () { IFS=$'\n' #Only split on newline -for CONTRIBUTOR in $(git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf); do - if shouldBeIncluded ${CONTRIBUTOR}; then - CONTRIBUTORS+=("${CONTRIBUTOR}") +for contributor in $(git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf) +do + if shouldBeIncluded $contributor; then + CONTRIBUTORS+=("$contributor") fi done unset IFS if [ ${#CONTRIBUTORS[@]} -ne 0 ]; then - cat >${AUTHORS_PATH} <<-'EOH' + cat >$AUTHORS_PATH <<-'EOH' # Thank you to everyone that made Pion possible. If you are interested in contributing # we would love to have you https://github.com/pion/webrtc/wiki/Contributing # # This file is auto generated, using git to list all individuals contributors. # see `.github/generate-authors.sh` for the scripting EOH - for i in "${CONTRIBUTORS[@]}"; do - echo "$i" >> ${AUTHORS_PATH} + for i in "${CONTRIBUTORS[@]}" + do + echo "$i" >> $AUTHORS_PATH done exit 0 fi diff --git a/.github/install-hooks.sh b/.github/install-hooks.sh index cd899d4..73d20a4 100755 --- a/.github/install-hooks.sh +++ b/.github/install-hooks.sh @@ -11,6 +11,6 @@ SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) -cp "${SCRIPT_PATH}/hooks/commit-msg.sh" "${SCRIPT_PATH}/../.git/hooks/commit-msg" -cp "${SCRIPT_PATH}/hooks/pre-commit.sh" "${SCRIPT_PATH}/../.git/hooks/pre-commit" -cp "${SCRIPT_PATH}/hooks/pre-push.sh" "${SCRIPT_PATH}/../.git/hooks/pre-push" +cp "$SCRIPT_PATH/hooks/commit-msg.sh" "$SCRIPT_PATH/../.git/hooks/commit-msg" +cp "$SCRIPT_PATH/hooks/pre-commit.sh" "$SCRIPT_PATH/../.git/hooks/pre-commit" +cp "$SCRIPT_PATH/hooks/pre-push.sh" "$SCRIPT_PATH/../.git/hooks/pre-push" diff --git a/.github/lint-commit-message.sh b/.github/lint-commit-message.sh index 2beb31d..010a332 100755 --- a/.github/lint-commit-message.sh +++ b/.github/lint-commit-message.sh @@ -58,7 +58,7 @@ if [ "$#" -eq 1 ]; then fi lint_commit_message "$(sed -n '/# Please enter the commit message for your changes. Lines starting/q;p' "$1")" else - for COMMIT in $(git rev-list --no-merges origin/master..); do - lint_commit_message "$(git log --format="%B" -n 1 ${COMMIT})" + for commit in $(git rev-list --no-merges origin/master..); do + lint_commit_message "$(git log --format="%B" -n 1 $commit)" done fi diff --git a/.github/lint-disallowed-functions-in-library.sh b/.github/lint-disallowed-functions-in-library.sh index 9dd988f..8ce5d09 100755 --- a/.github/lint-disallowed-functions-in-library.sh +++ b/.github/lint-disallowed-functions-in-library.sh @@ -13,31 +13,36 @@ set -e # Disallow usages of functions that cause the program to exit in the library code SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) -if [ -f ${SCRIPT_PATH}/.ci.conf ]; then +if [ -f ${SCRIPT_PATH}/.ci.conf ] +then . ${SCRIPT_PATH}/.ci.conf fi EXCLUDE_DIRECTORIES=${DISALLOWED_FUNCTIONS_EXCLUDED_DIRECTORIES:-"examples"} DISALLOWED_FUNCTIONS=('os.Exit(' 'panic(' 'Fatal(' 'Fatalf(' 'Fatalln(' 'fmt.Println(' 'fmt.Printf(' 'log.Print(' 'log.Println(' 'log.Printf(' 'print(' 'println(') -FILES=$( - find "${SCRIPT_PATH}/.." -name "*.go" \ +files=$( + find "$SCRIPT_PATH/.." -name "*.go" \ | grep -v -e '^.*_test.go$' \ - | while read FILE; do - EXCLUDED=false - for EXCLUDE_DIRECTORY in ${EXCLUDE_DIRECTORIES}; do - if [[ ${FILE} == */${EXCLUDE_DIRECTORY}/* ]]; then - EXCLUDED=true + | while read file + do + excluded=false + for ex in $EXCLUDE_DIRECTORIES + do + if [[ $file == */$ex/* ]] + then + excluded=true break fi done - ${EXCLUDED} || echo "${FILE}" + $excluded || echo "$file" done ) -for DISALLOWED_FUNCTION in "${DISALLOWED_FUNCTIONS[@]}"; do - if grep -e "\s${DISALLOWED_FUNCTION}" ${FILES} | grep -v -e 'nolint'; then - echo "${DISALLOWED_FUNCTION} may only be used in example code" +for disallowedFunction in "${DISALLOWED_FUNCTIONS[@]}" +do + if grep -e "\s$disallowedFunction" $files | grep -v -e 'nolint'; then + echo "$disallowedFunction may only be used in example code" exit 1 fi done diff --git a/.github/lint-filename.sh b/.github/lint-filename.sh index 3e7d1b9..81b3f14 100755 --- a/.github/lint-filename.sh +++ b/.github/lint-filename.sh @@ -14,11 +14,11 @@ set -e SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) GO_REGEX="^[a-zA-Z][a-zA-Z0-9_]*\.go$" -find "${SCRIPT_PATH}/.." -name "*.go" | while read FULLPATH; do - FILENAME=$(basename -- "${FULLPATH}") +find "$SCRIPT_PATH/.." -name "*.go" | while read fullpath; do + filename=$(basename -- "$fullpath") - if ! [[ ${FILENAME} =~ ${GO_REGEX} ]]; then - echo "${FILENAME} is not a valid filename for Go code, only alpha, numbers and underscores are supported" + if ! [[ $filename =~ $GO_REGEX ]]; then + echo "$filename is not a valid filename for Go code, only alpha, numbers and underscores are supported" exit 1 fi done diff --git a/.github/lint-no-trailing-newline-in-log-messages.sh b/.github/lint-no-trailing-newline-in-log-messages.sh index f0dad59..29cd4a2 100755 --- a/.github/lint-no-trailing-newline-in-log-messages.sh +++ b/.github/lint-no-trailing-newline-in-log-messages.sh @@ -13,25 +13,29 @@ set -e # Disallow usages of functions that cause the program to exit in the library code SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) -if [ -f ${SCRIPT_PATH}/.ci.conf ]; then +if [ -f ${SCRIPT_PATH}/.ci.conf ] +then . ${SCRIPT_PATH}/.ci.conf fi -FILES=$( - find "${SCRIPT_PATH}/.." -name "*.go" \ - | while read FILE; do - EXCLUDED=false - for EXCLUDE_DIRECTORY in ${EXCLUDE_DIRECTORIES}; do - if [[ $file == */${EXCLUDE_DIRECTORY}/* ]]; then - EXCLUDED=true +files=$( + find "$SCRIPT_PATH/.." -name "*.go" \ + | while read file + do + excluded=false + for ex in $EXCLUDE_DIRECTORIES + do + if [[ $file == */$ex/* ]] + then + excluded=true break fi done - ${EXCLUDED} || echo "${FILE}" + $excluded || echo "$file" done ) -if grep -E '\.(Trace|Debug|Info|Warn|Error)f?\("[^"]*\\n"\)?' ${FILES} | grep -v -e 'nolint'; then +if grep -E '\.(Trace|Debug|Info|Warn|Error)f?\("[^"]*\\n"\)?' $files | grep -v -e 'nolint'; then echo "Log format strings should have trailing new-line" exit 1 fi \ No newline at end of file diff --git a/AUTHORS.txt b/AUTHORS.txt index e8bfded..cb6271b 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -7,7 +7,6 @@ Adrian Cable Atsushi Watanabe backkem Hugo Arregui -Jeremiah Millay Jozef Kralik Juliusz Chroboczek Luke Curley @@ -16,7 +15,6 @@ OrlandoCo Sean DuBois Sean DuBois Sean DuBois -Steffen Vogel Winlin Woodrow Douglass Yutaka Takeda diff --git a/connctx/connctx_test.go b/connctx/connctx_test.go index 01a6159..4f9b1b6 100644 --- a/connctx/connctx_test.go +++ b/connctx/connctx_test.go @@ -56,7 +56,7 @@ func TestReadTImeout(t *testing.T) { b := make([]byte, 100) n, err := c.ReadContext(ctx, b) if err == nil { - t.Error("Read unexpectedly succeeded") + t.Error("Read unexpectedly successed") } if n != 0 { t.Errorf("Wrong data length, expected %d, got %d", 0, n) @@ -79,7 +79,7 @@ func TestReadCancel(t *testing.T) { b := make([]byte, 100) n, err := c.ReadContext(ctx, b) if err == nil { - t.Error("Read unexpectedly succeeded") + t.Error("Read unexpectedly successed") } if n != 0 { t.Errorf("Wrong data length, expected %d, got %d", 0, n) @@ -151,7 +151,7 @@ func TestWriteTimeout(t *testing.T) { b := make([]byte, 100) n, err := c.WriteContext(ctx, b) if err == nil { - t.Error("Write unexpectedly succeeded") + t.Error("Write unexpectedly successed") } if n != 0 { t.Errorf("Wrong data length, expected %d, got %d", 0, n) @@ -174,7 +174,7 @@ func TestWriteCancel(t *testing.T) { b := make([]byte, 100) n, err := c.WriteContext(ctx, b) if err == nil { - t.Error("Write unexpectedly succeeded") + t.Error("Write unexpectedly successed") } if n != 0 { t.Errorf("Wrong data length, expected %d, got %d", 0, n) diff --git a/examples/vnet-udpproxy/main.go b/examples/vnet-udpproxy/main.go index 2aef8c4..c776d65 100644 --- a/examples/vnet-udpproxy/main.go +++ b/examples/vnet-udpproxy/main.go @@ -1,5 +1,3 @@ -// Package main implements an example for the virtual Net -// UDP proxy. package main import ( @@ -27,13 +25,9 @@ func main() { } // Create a network and add to router, for example, for client. - clientNetwork, err := vnet.NewNet(&vnet.NetConfig{ + clientNetwork := vnet.NewNet(&vnet.NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - panic(err) - } - if err = router.AddNet(clientNetwork); err != nil { panic(err) } diff --git a/go.mod b/go.mod index 0ef935c..be760b9 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ retract v0.14.0 require ( github.com/pion/logging v0.2.2 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.7.1 golang.org/x/net v0.1.0 golang.org/x/sys v0.2.0 ) diff --git a/go.sum b/go.sum index dedbe6c..31ce0fd 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,12 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -44,6 +39,5 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/net.go b/net.go deleted file mode 100644 index da601f7..0000000 --- a/net.go +++ /dev/null @@ -1,415 +0,0 @@ -// Package transport implements various networking related -// functions used throughout the Pion modules. -package transport - -import ( - "errors" - "io" - "net" - "time" -) - -var ( - // ErrNoAddressAssigned ... - ErrNoAddressAssigned = errors.New("no address assigned") - // ErrNotSupported ... - ErrNotSupported = errors.New("not supported yey") - // ErrInterfaceNotFound ... - ErrInterfaceNotFound = errors.New("interface not found") - // ErrNotUDPAddress ... - ErrNotUDPAddress = errors.New("not a UDP address") -) - -// Net is an interface providing common networking functions which are -// similar to the functions provided by standard net package. -type Net interface { - // ListenPacket announces on the local network address. - // - // The network must be "udp", "udp4", "udp6", "unixgram", or an IP - // transport. The IP transports are "ip", "ip4", or "ip6" followed by - // a colon and a literal protocol number or a protocol name, as in - // "ip:1" or "ip:icmp". - // - // For UDP and IP networks, if the host in the address parameter is - // empty or a literal unspecified IP address, ListenPacket listens on - // all available IP addresses of the local system except multicast IP - // addresses. - // To only use IPv4, use network "udp4" or "ip4:proto". - // The address can use a host name, but this is not recommended, - // because it will create a listener for at most one of the host's IP - // addresses. - // If the port in the address parameter is empty or "0", as in - // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen. - // The LocalAddr method of PacketConn can be used to discover the - // chosen port. - // - // See func Dial for a description of the network and address - // parameters. - // - // ListenPacket uses context.Background internally; to specify the context, use - // ListenConfig.ListenPacket. - ListenPacket(network string, address string) (net.PacketConn, error) - - // ListenUDP acts like ListenPacket for UDP networks. - // - // The network must be a UDP network name; see func Dial for details. - // - // If the IP field of laddr is nil or an unspecified IP address, - // ListenUDP listens on all available IP addresses of the local system - // except multicast IP addresses. - // If the Port field of laddr is 0, a port number is automatically - // chosen. - ListenUDP(network string, locAddr *net.UDPAddr) (UDPConn, error) - - // ListenTCP acts like Listen for TCP networks. - // - // The network must be a TCP network name; see func Dial for details. - // - // If the IP field of laddr is nil or an unspecified IP address, - // ListenTCP listens on all available unicast and anycast IP addresses - // of the local system. - // If the Port field of laddr is 0, a port number is automatically - // chosen. - ListenTCP(network string, laddr *net.TCPAddr) (TCPListener, error) - - // Dial connects to the address on the named network. - // - // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), - // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" - // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and - // "unixpacket". - // - // For TCP and UDP networks, the address has the form "host:port". - // The host must be a literal IP address, or a host name that can be - // resolved to IP addresses. - // The port must be a literal port number or a service name. - // If the host is a literal IPv6 address it must be enclosed in square - // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80". - // The zone specifies the scope of the literal IPv6 address as defined - // in RFC 4007. - // The functions JoinHostPort and SplitHostPort manipulate a pair of - // host and port in this form. - // When using TCP, and the host resolves to multiple IP addresses, - // Dial will try each IP address in order until one succeeds. - // - // Examples: - // - // Dial("tcp", "golang.org:http") - // Dial("tcp", "192.0.2.1:http") - // Dial("tcp", "198.51.100.1:80") - // Dial("udp", "[2001:db8::1]:domain") - // Dial("udp", "[fe80::1%lo0]:53") - // Dial("tcp", ":80") - // - // For IP networks, the network must be "ip", "ip4" or "ip6" followed - // by a colon and a literal protocol number or a protocol name, and - // the address has the form "host". The host must be a literal IP - // address or a literal IPv6 address with zone. - // It depends on each operating system how the operating system - // behaves with a non-well known protocol number such as "0" or "255". - // - // Examples: - // - // Dial("ip4:1", "192.0.2.1") - // Dial("ip6:ipv6-icmp", "2001:db8::1") - // Dial("ip6:58", "fe80::1%lo0") - // - // For TCP, UDP and IP networks, if the host is empty or a literal - // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for - // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is - // assumed. - // - // For Unix networks, the address must be a file system path. - Dial(network, address string) (net.Conn, error) - - // DialUDP acts like Dial for UDP networks. - // - // The network must be a UDP network name; see func Dial for details. - // - // If laddr is nil, a local address is automatically chosen. - // If the IP field of raddr is nil or an unspecified IP address, the - // local system is assumed. - DialUDP(network string, laddr, raddr *net.UDPAddr) (UDPConn, error) - - // DialTCP acts like Dial for TCP networks. - // - // The network must be a TCP network name; see func Dial for details. - // - // If laddr is nil, a local address is automatically chosen. - // If the IP field of raddr is nil or an unspecified IP address, the - // local system is assumed. - DialTCP(network string, laddr, raddr *net.TCPAddr) (TCPConn, error) - - // ResolveIPAddr returns an address of IP end point. - // - // The network must be an IP network name. - // - // If the host in the address parameter is not a literal IP address, - // ResolveIPAddr resolves the address to an address of IP end point. - // Otherwise, it parses the address as a literal IP address. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveIPAddr(network, address string) (*net.IPAddr, error) - - // ResolveUDPAddr returns an address of UDP end point. - // - // The network must be a UDP network name. - // - // If the host in the address parameter is not a literal IP address or - // the port is not a literal port number, ResolveUDPAddr resolves the - // address to an address of UDP end point. - // Otherwise, it parses the address as a pair of literal IP address - // and port number. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveUDPAddr(network, address string) (*net.UDPAddr, error) - - // ResolveTCPAddr returns an address of TCP end point. - // - // The network must be a TCP network name. - // - // If the host in the address parameter is not a literal IP address or - // the port is not a literal port number, ResolveTCPAddr resolves the - // address to an address of TCP end point. - // Otherwise, it parses the address as a pair of literal IP address - // and port number. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveTCPAddr(network, address string) (*net.TCPAddr, error) - - // Interfaces returns a list of the system's network interfaces. - Interfaces() ([]*Interface, error) - - // InterfaceByIndex returns the interface specified by index. - // - // On Solaris, it returns one of the logical network interfaces - // sharing the logical data link; for more precision use - // InterfaceByName. - InterfaceByIndex(index int) (*Interface, error) - - // InterfaceByName returns the interface specified by name. - InterfaceByName(name string) (*Interface, error) - - // The following functions are extensions to Go's standard net package - - CreateDialer(dialer *net.Dialer) Dialer -} - -// Dialer is identical to net.Dialer excepts that its methods -// (Dial, DialContext) are overridden to use the Net interface. -// Use vnet.CreateDialer() to create an instance of this Dialer. -type Dialer interface { - Dial(network, address string) (net.Conn, error) -} - -// UDPConn is packet-oriented connection for UDP. -type UDPConn interface { - // Close closes the connection. - // Any blocked Read or Write operations will be unblocked and return errors. - Close() error - - // LocalAddr returns the local network address, if known. - LocalAddr() net.Addr - - // RemoteAddr returns the remote network address, if known. - RemoteAddr() net.Addr - - // SetDeadline sets the read and write deadlines associated - // with the connection. It is equivalent to calling both - // SetReadDeadline and SetWriteDeadline. - // - // A deadline is an absolute time after which I/O operations - // fail instead of blocking. The deadline applies to all future - // and pending I/O, not just the immediately following call to - // Read or Write. After a deadline has been exceeded, the - // connection can be refreshed by setting a deadline in the future. - // - // If the deadline is exceeded a call to Read or Write or to other - // I/O methods will return an error that wraps os.ErrDeadlineExceeded. - // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). - // The error's Timeout method will return true, but note that there - // are other possible errors for which the Timeout method will - // return true even if the deadline has not been exceeded. - // - // An idle timeout can be implemented by repeatedly extending - // the deadline after successful Read or Write calls. - // - // A zero value for t means I/O operations will not time out. - SetDeadline(t time.Time) error - - // SetReadDeadline sets the deadline for future Read calls - // and any currently-blocked Read call. - // A zero value for t means Read will not time out. - SetReadDeadline(t time.Time) error - - // SetWriteDeadline sets the deadline for future Write calls - // and any currently-blocked Write call. - // Even if write times out, it may return n > 0, indicating that - // some of the data was successfully written. - // A zero value for t means Write will not time out. - SetWriteDeadline(t time.Time) error - - // SetReadBuffer sets the size of the operating system's - // receive buffer associated with the connection. - SetReadBuffer(bytes int) error - - // SetWriteBuffer sets the size of the operating system's - // transmit buffer associated with the connection. - SetWriteBuffer(bytes int) error - - // Read reads data from the connection. - // Read can be made to time out and return an error after a fixed - // time limit; see SetDeadline and SetReadDeadline. - Read(b []byte) (n int, err error) - - // ReadFrom reads a packet from the connection, - // copying the payload into p. It returns the number of - // bytes copied into p and the return address that - // was on the packet. - // It returns the number of bytes read (0 <= n <= len(p)) - // and any error encountered. Callers should always process - // the n > 0 bytes returned before considering the error err. - // ReadFrom can be made to time out and return an error after a - // fixed time limit; see SetDeadline and SetReadDeadline. - ReadFrom(p []byte) (n int, addr net.Addr, err error) - - // ReadFromUDP acts like ReadFrom but returns a UDPAddr. - ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) - - // ReadMsgUDP reads a message from c, copying the payload into b and - // the associated out-of-band data into oob. It returns the number of - // bytes copied into b, the number of bytes copied into oob, the flags - // that were set on the message and the source address of the message. - // - // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be - // used to manipulate IP-level socket options in oob. - ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) - - // Write writes data to the connection. - // Write can be made to time out and return an error after a fixed - // time limit; see SetDeadline and SetWriteDeadline. - Write(b []byte) (n int, err error) - - // WriteTo writes a packet with payload p to addr. - // WriteTo can be made to time out and return an Error after a - // fixed time limit; see SetDeadline and SetWriteDeadline. - // On packet-oriented connections, write timeouts are rare. - WriteTo(p []byte, addr net.Addr) (n int, err error) - - // WriteToUDP acts like WriteTo but takes a UDPAddr. - WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) - - // WriteMsgUDP writes a message to addr via c if c isn't connected, or - // to c's remote address if c is connected (in which case addr must be - // nil). The payload is copied from b and the associated out-of-band - // data is copied from oob. It returns the number of payload and - // out-of-band bytes written. - // - // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be - // used to manipulate IP-level socket options in oob. - WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) -} - -// TCPConn is an interface for TCP network connections. -type TCPConn interface { - net.Conn - - // CloseRead shuts down the reading side of the TCP connection. - // Most callers should just use Close. - CloseRead() error - - // CloseWrite shuts down the writing side of the TCP connection. - // Most callers should just use Close. - CloseWrite() error - - // ReadFrom implements the io.ReaderFrom ReadFrom method. - ReadFrom(r io.Reader) (int64, error) - - // SetLinger sets the behavior of Close on a connection which still - // has data waiting to be sent or to be acknowledged. - // - // If sec < 0 (the default), the operating system finishes sending the - // data in the background. - // - // If sec == 0, the operating system discards any unsent or - // unacknowledged data. - // - // If sec > 0, the data is sent in the background as with sec < 0. On - // some operating systems after sec seconds have elapsed any remaining - // unsent data may be discarded. - SetLinger(sec int) error - - // SetKeepAlive sets whether the operating system should send - // keep-alive messages on the connection. - SetKeepAlive(keepalive bool) error - - // SetKeepAlivePeriod sets period between keep-alives. - SetKeepAlivePeriod(d time.Duration) error - - // SetNoDelay controls whether the operating system should delay - // packet transmission in hopes of sending fewer packets (Nagle's - // algorithm). The default is true (no delay), meaning that data is - // sent as soon as possible after a Write. - SetNoDelay(noDelay bool) error - - // SetWriteBuffer sets the size of the operating system's - // transmit buffer associated with the connection. - SetWriteBuffer(bytes int) error - - // SetReadBuffer sets the size of the operating system's - // receive buffer associated with the connection. - SetReadBuffer(bytes int) error -} - -// TCPListener is a TCP network listener. Clients should typically -// use variables of type Listener instead of assuming TCP. -type TCPListener interface { - net.Listener - - // AcceptTCP accepts the next incoming call and returns the new - // connection. - AcceptTCP() (TCPConn, error) - - // SetDeadline sets the deadline associated with the listener. - // A zero time value disables the deadline. - SetDeadline(t time.Time) error -} - -// Interface wraps a standard net.Interfaces and its assigned addresses -type Interface struct { - net.Interface - addrs []net.Addr -} - -// NewInterface creates a new interface based of a standard net.Interface -func NewInterface(ifc net.Interface) *Interface { - return &Interface{ - Interface: ifc, - addrs: nil, - } -} - -// AddAddress adds a new address to the interface -func (ifc *Interface) AddAddress(addr net.Addr) { - ifc.addrs = append(ifc.addrs, addr) -} - -// Addresses returns a slice of configured addresses on the interface -func (ifc *Interface) Addresses() ([]net.Addr, error) { - if len(ifc.addrs) == 0 { - return nil, ErrNoAddressAssigned - } - return ifc.addrs, nil -} diff --git a/packetio/buffer.go b/packetio/buffer.go index 77b9d8d..97d86f8 100644 --- a/packetio/buffer.go +++ b/packetio/buffer.go @@ -77,42 +77,42 @@ func (b *Buffer) available(size int) bool { // grow increases the size of the buffer. If it returns nil, then the // buffer has been grown. It returns ErrFull if hits a limit. func (b *Buffer) grow() error { - var newSize int + var newsize int if len(b.data) < cutoffSize { - newSize = 2 * len(b.data) + newsize = 2 * len(b.data) } else { - newSize = 5 * len(b.data) / 4 + newsize = 5 * len(b.data) / 4 } - if newSize < minSize { - newSize = minSize + if newsize < minSize { + newsize = minSize } - if (b.limitSize <= 0 || sizeHardLimit) && newSize > maxSize { - newSize = maxSize + if (b.limitSize <= 0 || sizeHardlimit) && newsize > maxSize { + newsize = maxSize } // one byte slack - if b.limitSize > 0 && newSize > b.limitSize+1 { - newSize = b.limitSize + 1 + if b.limitSize > 0 && newsize > b.limitSize+1 { + newsize = b.limitSize + 1 } - if newSize <= len(b.data) { + if newsize <= len(b.data) { return ErrFull } - newData := make([]byte, newSize) + newdata := make([]byte, newsize) var n int if b.head <= b.tail { // data was contiguous - n = copy(newData, b.data[b.head:b.tail]) + n = copy(newdata, b.data[b.head:b.tail]) } else { - // data was discontinuous - n = copy(newData, b.data[b.head:]) - n += copy(newData[n:], b.data[:b.tail]) + // data was discontiguous + n = copy(newdata, b.data[b.head:]) + n += copy(newdata[n:], b.data[:b.tail]) } b.head = 0 b.tail = n - b.data = newData + b.data = newdata return nil } @@ -329,9 +329,9 @@ func (b *Buffer) size() int { // Causes Write to return ErrFull when this limit is reached. // A zero value means 4MB since v0.11.0. // -// User can set packetioSizeHardLimit build tag to enable 4MB hard limit. -// When packetioSizeHardLimit build tag is set, SetLimitSize exceeding -// the hard limit will be silently discarded. +// User can set packetioSizeHardlimit build tag to enable 4MB hardlimit. +// When packetioSizeHardlimit build tag is set, SetLimitSize exceeding +// the hardlimit will be silently discarded. func (b *Buffer) SetLimitSize(limit int) { b.mutex.Lock() defer b.mutex.Unlock() diff --git a/packetio/buffer_test.go b/packetio/buffer_test.go index d2dd804..85fea8a 100644 --- a/packetio/buffer_test.go +++ b/packetio/buffer_test.go @@ -321,8 +321,8 @@ func TestBufferLimitSize(t *testing.T) { } func TestBufferLimitSizes(t *testing.T) { - if sizeHardLimit { - t.Skip("skipping since packetioSizeHardLimit is enabled") + if sizeHardlimit { + t.Skip("skipping since packetioSizeHardlimit is enabled") } sizes := []int{ 128 * 1024, @@ -337,7 +337,7 @@ func TestBufferLimitSizes(t *testing.T) { size := size name := "default" if size > 0 { - name = fmt.Sprintf("%dkBytes", size/1024) + name = fmt.Sprintf("%dkbytes", size/1024) } t.Run(name, func(t *testing.T) { diff --git a/packetio/hardlimit.go b/packetio/hardlimit.go index 9f4fc5e..5ddacc7 100644 --- a/packetio/hardlimit.go +++ b/packetio/hardlimit.go @@ -1,6 +1,5 @@ -//go:build packetioSizeHardlimit // +build packetioSizeHardlimit package packetio -const sizeHardLimit = true +const sizeHardlimit = true diff --git a/packetio/no_hardlimit.go b/packetio/no_hardlimit.go index 869e0b6..ccbb615 100644 --- a/packetio/no_hardlimit.go +++ b/packetio/no_hardlimit.go @@ -3,4 +3,4 @@ package packetio -const sizeHardLimit = false +const sizeHardlimit = false diff --git a/replaydetector/replaydetector.go b/replaydetector/replaydetector.go index 297f9f3..d942002 100644 --- a/replaydetector/replaydetector.go +++ b/replaydetector/replaydetector.go @@ -55,7 +55,7 @@ func (d *slidingWindowDetector) Check(seq uint64) (accept func(), ok bool) { } // WithWrap creates ReplayDetector allowing sequence wrapping. -// This is suitable for short bit width counter like SRTP and SRTCP. +// This is suitable for short bitwidth counter like SRTP and SRTCP. func WithWrap(windowSize uint, maxSeq uint64) ReplayDetector { return &wrappedSlidingWindowDetector{ maxSeq: maxSeq, diff --git a/replaydetector/replaydetector_test.go b/replaydetector/replaydetector_test.go index 7b57766..33ca22c 100644 --- a/replaydetector/replaydetector_test.go +++ b/replaydetector/replaydetector_test.go @@ -94,7 +94,7 @@ func TestReplayDetector(t *testing.T) { []uint64{24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128}, nil, }, - "ContinuousReplayed": { + "ContinuouesReplayed": { 8, 0x0000FFFFFFFFFFFF, []uint64{16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, []bool{ diff --git a/stdnet/net.go b/stdnet/net.go deleted file mode 100644 index d755bed..0000000 --- a/stdnet/net.go +++ /dev/null @@ -1,164 +0,0 @@ -// Package stdnet implements the transport.Net interface -// using methods from Go's standard net package. -package stdnet - -import ( - "fmt" - "net" - - "github.com/pion/transport" -) - -const ( - lo0String = "lo0String" - udpString = "udp" -) - -// Net is an implementation of the net.Net interface -// based on functions of the standard net package. -type Net struct { - interfaces []*transport.Interface -} - -// NewNet creates a new StdNet instance. -func NewNet() (*Net, error) { - n := &Net{} - - return n, n.UpdateInterfaces() -} - -// Compile-time assertion -var _ transport.Net = &Net{} - -// UpdateInterfaces updates the internal list of network interfaces -// and associated addresses. -func (n *Net) UpdateInterfaces() error { - ifs := []*transport.Interface{} - - oifs, err := net.Interfaces() - if err != nil { - return err - } - - for _, oif := range oifs { - ifc := transport.NewInterface(oif) - - addrs, err := oif.Addrs() - if err != nil { - return err - } - - for _, addr := range addrs { - ifc.AddAddress(addr) - } - - ifs = append(ifs, ifc) - } - - n.interfaces = ifs - - return nil -} - -// Interfaces returns a slice of interfaces which are available on the -// system -func (n *Net) Interfaces() ([]*transport.Interface, error) { - return n.interfaces, nil -} - -// InterfaceByIndex returns the interface specified by index. -// -// On Solaris, it returns one of the logical network interfaces -// sharing the logical data link; for more precision use -// InterfaceByName. -func (n *Net) InterfaceByIndex(index int) (*transport.Interface, error) { - for _, ifc := range n.interfaces { - if ifc.Index == index { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: index=%d", transport.ErrInterfaceNotFound, index) -} - -// InterfaceByName returns the interface specified by name. -func (n *Net) InterfaceByName(name string) (*transport.Interface, error) { - for _, ifc := range n.interfaces { - if ifc.Name == name { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, name) -} - -// ListenPacket announces on the local network address. -func (n *Net) ListenPacket(network string, address string) (net.PacketConn, error) { - return net.ListenPacket(network, address) -} - -// ListenUDP acts like ListenPacket for UDP networks. -func (n *Net) ListenUDP(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) { - return net.ListenUDP(network, locAddr) -} - -// Dial connects to the address on the named network. -func (n *Net) Dial(network, address string) (net.Conn, error) { - return net.Dial(network, address) -} - -// DialUDP acts like Dial for UDP networks. -func (n *Net) DialUDP(network string, laddr, raddr *net.UDPAddr) (transport.UDPConn, error) { - return net.DialUDP(network, laddr, raddr) -} - -// ResolveIPAddr returns an address of IP end point. -func (n *Net) ResolveIPAddr(network, address string) (*net.IPAddr, error) { - return net.ResolveIPAddr(network, address) -} - -// ResolveUDPAddr returns an address of UDP end point. -func (n *Net) ResolveUDPAddr(network, address string) (*net.UDPAddr, error) { - return net.ResolveUDPAddr(network, address) -} - -// ResolveTCPAddr returns an address of TCP end point. -func (n *Net) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { - return net.ResolveTCPAddr(network, address) -} - -// DialTCP acts like Dial for TCP networks. -func (n *Net) DialTCP(network string, laddr, raddr *net.TCPAddr) (transport.TCPConn, error) { - return net.DialTCP(network, laddr, raddr) -} - -// ListenTCP acts like Listen for TCP networks. -func (n *Net) ListenTCP(network string, laddr *net.TCPAddr) (transport.TCPListener, error) { - l, err := net.ListenTCP(network, laddr) - if err != nil { - return nil, err - } - - return tcpListener{l}, nil -} - -type tcpListener struct { - *net.TCPListener -} - -func (l tcpListener) AcceptTCP() (transport.TCPConn, error) { - return l.TCPListener.AcceptTCP() -} - -type stdDialer struct { - *net.Dialer -} - -func (d stdDialer) Dial(network, address string) (net.Conn, error) { - return d.Dialer.Dial(network, address) -} - -// CreateDialer creates an instance of vnet.Dialer -func (n *Net) CreateDialer(d *net.Dialer) transport.Dialer { - return stdDialer{d} -} diff --git a/test/bridge.go b/test/bridge.go index de56c66..f63af33 100644 --- a/test/bridge.go +++ b/test/bridge.go @@ -59,7 +59,7 @@ func (e *netError) Timeout() bool { } func (e *netError) Temporary() bool { - return e.temporary + return e.timeout } // Read reads data, block until the data becomes available. diff --git a/test/bridge_test.go b/test/bridge_test.go index 073cf59..47748e5 100644 --- a/test/bridge_test.go +++ b/test/bridge_test.go @@ -469,7 +469,7 @@ func TestNetTest(t *testing.T) { return &closePropagator{conn0, conn1}, &closePropagator{conn1, conn0}, func() { // RacyRead test leave receive buffer filled. - // As net.Conn.Read() should return received data even after Close()-ed, + // As net.Conn.Read() shoud return received data even after Close()-ed, // queue must be cleared explicitly. br.clear() _ = conn0.Close() diff --git a/test/util.go b/test/util.go index 48906d7..8924d4c 100644 --- a/test/util.go +++ b/test/util.go @@ -85,17 +85,17 @@ func GatherErrs(c chan error) []error { // FlattenErrs flattens a slice of errors into a single error func FlattenErrs(errs []error) error { - var errStrings []string + var errstrings []string for _, err := range errs { if err != nil { - errStrings = append(errStrings, err.Error()) + errstrings = append(errstrings, err.Error()) } } - if len(errStrings) == 0 { + if len(errstrings) == 0 { return nil } - return fmt.Errorf("%w %s", errFlattenErrs, strings.Join(errStrings, "\n")) + return fmt.Errorf("%w %s", errFlattenErrs, strings.Join(errstrings, "\n")) } diff --git a/utils/xor/xor_arm64.go b/utils/xor/xor_arm64.go index 30b5770..607a18c 100644 --- a/utils/xor/xor_arm64.go +++ b/utils/xor/xor_arm64.go @@ -8,7 +8,6 @@ package xor // XorBytes xors the bytes in a and b. The destination should have enough // space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// //revive:disable-next-line func XorBytes(dst, a, b []byte) int { n := len(a) diff --git a/vnet/README.md b/vnet/README.md index bd0af25..b502f9f 100644 --- a/vnet/README.md +++ b/vnet/README.md @@ -38,8 +38,8 @@ A virtual network layer for pion. : +-------+ : ...................................... Note: - o: NIC (Network Interface Controller) - [1]: Net implements NIC interface. + o: NIC (Netork Interface Controller) + [1]: Net implments NIC interface. [2]: Root router has no NAT. All child routers have a NAT always. [3]: Router implements NIC interface for accesses from the parent router. @@ -61,12 +61,12 @@ Net provides 3 interfaces: +---------+ 1 * +-----------+ 1 * +-----------+ 1 * +------+ ..| :Router |----+------>o--| :Net |<>------|:Interface |<>------|:Addr | +---------+ | NIC +-----------+ +-----------+ +------+ - | <> (transport.Interface) (net.Addr) + | <> (vnet.Interface) (net.Addr) | | * +-----------+ 1 * +-----------+ 1 * +------+ +------>o--| :Router |<>------|:Interface |<>------|:Addr | NIC +-----------+ +-----------+ +------+ - <> (transport.Interface) (net.Addr) + <> (vnet.Interface) (net.Addr) ``` > The instance of `Net` will be the one passed around the project. @@ -76,8 +76,8 @@ Net provides 3 interfaces: ## Implementation ### Design Policy -* Each pion package should have config object which has `Net` (of type `transport.Net`) property. - - Just like how we distribute `LoggerFactory` throughout the pion project. +* Each pion package should have config object which has `Net` (of type vnet.Net) property. (just like how + we distribute `LoggerFactory` throughout the pion project. * DNS => a simple dictionary (global)? * Each Net has routing capability (a goroutine) * Use interface provided net package as much as possible @@ -86,8 +86,10 @@ Net provides 3 interfaces: - Easy to control / monitor (stats, etc) * Root router has no NAT (== Internet / WAN) * Non-root router has a NAT always -* When a Net is instantiated, it will automatically add `lo0` and `eth0` interface, and `lo0` will have one IP address, 127.0.0.1. (this is not used in pion/ice, however) -* When a Net is added to a router, the router automatically assign an IP address for `eth0` interface. +* When a Net is instantiated, it will automatically add `lo0` and `eth0` interface, and `lo0` will +have one IP address, 127.0.0.1. (this is not used in pion/ice, however) +* When a Net is added to a router, the router automatically assign an IP address for `eth0` +interface. - For simplicity * User data won't fragment, but optionally drop chunk larger than MTU * IPv6 is not supported @@ -96,14 +98,13 @@ Net provides 3 interfaces: 1. Create a root router (WAN) 1. Create child routers and add to its parent (forms a tree, don't create a loop!) 1. Add instances of Net to each routers -1. Call Stop(), or Stop(), on the top router, which propagates all other routers +1. Call Stop(), or Stop(), on the top router, which propages all other routers #### Example: WAN with one endpoint (vnet) ```go import ( "net" - "github.com/pion/transport" "github.com/pion/transport/vnet" "github.com/pion/logging" ) @@ -140,7 +141,7 @@ if err = wan.Start(); err != nil { // // Stop the router. -// This will stop all internal Go routines in the router tree. +// This will stop all internal goroutines in the router tree. // (No need to call Stop() on child routers) if err = wan.Stop(); err != nil { // handle error @@ -157,17 +158,17 @@ instance (`nw` in the above example) like this: ```go type AgentConfig struct { : - Net: transport.Net, + Net: *vnet.Net, } type Agent struct { : - net: transport.Net, + net: *vnet.Net, } func NetAgent(config *AgentConfig) *Agent { if config.Net == nil { - config.Net = vnet.NewNet() + config.Net = vnet.NewNet(nil) // defaults to native operation } return &Agent { @@ -188,25 +189,26 @@ func (a *Agent) listenUDP(...) error { } ``` + ### Compatibility and Support Status -|`net`
(built-in) |`vnet` |Note | -|:--- |:--- |:--- | -| net.Interfaces() | a.net.Interfaces() | | -| net.InterfaceByName() | a.net.InterfaceByName() | | -| net.ResolveUDPAddr() | a.net.ResolveUDPAddr() | | -| net.ListenPacket() | a.net.ListenPacket() | | -| net.ListenUDP() | a.net.ListenUDP() | ListenPacket() is recommended | -| net.Listen() | a.net.Listen() | TODO) | -| net.ListenTCP() | (not supported) | Listen() would be recommended | -| net.Dial() | a.net.Dial() | | -| net.DialUDP() | a.net.DialUDP() | | -| net.DialTCP() | (not supported) | | -| net.Interface | transport.Interface | | -| net.PacketConn | (use it as-is) | | -| net.UDPConn | transport.UDPConn | | -| net.TCPConn | transport.TCPConn | TODO: Use net.Conn in your code | -| net.Dialer | transport.Dialer | Use a.net.CreateDialer() to create it.
The use of vnet.Dialer is currently experimental. | +|`net`
(built-in)|`vnet`|Note| +|---|---|---| +|net.Interfaces()|a.net.Interfaces()|| +|net.InterfaceByName()|a.net.InterfaceByName()|| +|net.ResolveUDPAddr()|a.net.ResolveUDPAddr()|| +|net.ListenPacket()|a.net.ListenPacket()|| +|net.ListenUDP()|a.net.ListenUDP()|(ListenPacket() is recommended)| +|net.Listen()|a.net.Listen()|(TODO)| +|net.ListenTCP()|(not supported)|(Listen() would be recommended)| +|net.Dial()|a.net.Dial()|| +|net.DialUDP()|a.net.DialUDP()|| +|net.DialTCP()|(not supported)|| +|net.Interface|vnet.Interface|| +|net.PacketConn|(use it as-is)|| +|net.UDPConn|vnet.UDPConn|Use vnet.UDPPacketConn in your code| +|net.TCPConn|vnet.TCPConn|(TODO)|Use net.Conn in your code| +|net.Dialer|vnet.Dialer|Use a.net.CreateDialer() to create it.
The use of vnet.Dialer is currently experimental.| > `a.net` is an instance of Net class, and types are defined under the package name `vnet` @@ -219,7 +221,7 @@ func (a *Agent) listenUDP(...) error { * Support of IPv6 * Write a bunch of examples for building virtual networks. * Add network impairment features (on Router) - - Introduce latency / jitter + - Introduce lantecy / jitter - Packet filtering handler (allow selectively drop packets, etc.) * Add statistics data retrieval - Total number of packets forward by each router @@ -228,4 +230,10 @@ func (a *Agent) listenUDP(...) error { ## References * [Comparing Simulated Packet Loss and RealWorld Network Congestion](https://www.riverbed.com/document/fpo/WhitePaper-Riverbed-SimulatedPacketLoss.pdf) -* [wireguard-go using GVisor's netstack](https://github.com/WireGuard/wireguard-go/tree/master/tun/netstack) \ No newline at end of file + +### Code experiments +* [CIDR and IPMask](https://play.golang.org/p/B7OBhkZqjmj) +* [Test with net.IP](https://play.golang.org/p/AgXd23wKY4W) +* [ListenPacket](https://play.golang.org/p/d4vasbnRimQ) +* [isDottedIP()](https://play.golang.org/p/t4aZ47TgJfO) +* [SplitHostPort](https://play.golang.org/p/JtvurlcMbhn) diff --git a/vnet/chunk.go b/vnet/chunk.go index 56294a2..7a87a2f 100644 --- a/vnet/chunk.go +++ b/vnet/chunk.go @@ -155,7 +155,7 @@ func (c *chunkUDP) Clone() Chunk { } func (c *chunkUDP) Network() string { - return udp + return udpString } func (c *chunkUDP) String() string { @@ -170,7 +170,7 @@ func (c *chunkUDP) String() string { } func (c *chunkUDP) setSourceAddr(address string) error { - addr, err := net.ResolveUDPAddr(udp, address) + addr, err := net.ResolveUDPAddr(udpString, address) if err != nil { return err } @@ -180,7 +180,7 @@ func (c *chunkUDP) setSourceAddr(address string) error { } func (c *chunkUDP) setDestinationAddr(address string) error { - addr, err := net.ResolveUDPAddr(udp, address) + addr, err := net.ResolveUDPAddr(udpString, address) if err != nil { return err } diff --git a/vnet/chunk_test.go b/vnet/chunk_test.go index 5859c1f..fff5f77 100644 --- a/vnet/chunk_test.go +++ b/vnet/chunk_test.go @@ -41,7 +41,7 @@ func TestChunk(t *testing.T) { var c Chunk = newChunkUDP(src, dst) str := c.String() log.Debugf("chunk: %s", str) - assert.Equal(t, udp, c.Network(), "should match") + assert.Equal(t, udpString, c.Network(), "should match") assert.True(t, strings.Contains(str, src.Network()), "should include network type") assert.True(t, strings.Contains(str, src.String()), "should include address") assert.True(t, strings.Contains(str, dst.String()), "should include address") @@ -67,7 +67,7 @@ func TestChunk(t *testing.T) { assert.Equal(t, uc.tag, uc.Tag(), "should match") // Verify cloned chunk was not affected by the changes to original chunk - uc.userData[0] = []byte("!")[0] // original: "Hello" -> "Hell!" + uc.userData[0] = []byte("!")[0] // oroginal: "Hello" -> "Hell!" assert.Equal(t, "Hello", string(cloned.userData), "should match") assert.Equal(t, "192.168.0.2:1234", cloned.SourceAddr().String()) assert.True(t, cloned.getSourceIP().Equal(src.IP), "ip should match") @@ -117,7 +117,7 @@ func TestChunk(t *testing.T) { assert.Equal(t, tc.tag, tc.Tag(), "should match") // Verify cloned chunk was not affected by the changes to original chunk - tc.userData[0] = []byte("!")[0] // original: "Hello" -> "Hell!" + tc.userData[0] = []byte("!")[0] // oroginal: "Hello" -> "Hell!" assert.Equal(t, "Hello", string(cloned.userData), "should match") assert.Equal(t, "192.168.0.2:1234", cloned.SourceAddr().String()) assert.True(t, cloned.getSourceIP().Equal(src.IP), "ip should match") diff --git a/vnet/conn.go b/vnet/conn.go index 729dfaf..f4b8b92 100644 --- a/vnet/conn.go +++ b/vnet/conn.go @@ -2,14 +2,11 @@ package vnet import ( "errors" - "fmt" "io" "math" "net" "sync" "time" - - "github.com/pion/transport" ) const ( @@ -25,6 +22,14 @@ var ( errNoRemAddr = errors.New("no remAddr defined") ) +// UDPPacketConn is packet-oriented connection for UDP. +type UDPPacketConn interface { + net.PacketConn + Read(b []byte) (int, error) + RemoteAddr() net.Addr + Write(b []byte) (int, error) +} + // vNet implements this type connObserver interface { write(c Chunk) error @@ -33,7 +38,7 @@ type connObserver interface { } // UDPConn is the implementation of the Conn and PacketConn interfaces for UDP network connections. -// compatible with net.PacketConn and net.Conn +// comatible with net.PacketConn and net.Conn type UDPConn struct { locAddr *net.UDPAddr // read-only remAddr *net.UDPAddr // read-only @@ -44,8 +49,6 @@ type UDPConn struct { readTimer *time.Timer // thread-safe } -var _ transport.UDPConn = &UDPConn{} - func newUDPConn(locAddr, remAddr *net.UDPAddr, obs connObserver) (*UDPConn, error) { if obs == nil { return nil, errObsCannotBeNil @@ -60,84 +63,6 @@ func newUDPConn(locAddr, remAddr *net.UDPAddr, obs connObserver) (*UDPConn, erro }, nil } -// Close closes the connection. -// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. -func (c *UDPConn) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - - if c.closed { - return errAlreadyClosed - } - c.closed = true - close(c.readCh) - - c.obs.onClosed(c.locAddr) - return nil -} - -// LocalAddr returns the local network address. -func (c *UDPConn) LocalAddr() net.Addr { - return c.locAddr -} - -// RemoteAddr returns the remote network address. -func (c *UDPConn) RemoteAddr() net.Addr { - return c.remAddr -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. It is equivalent to calling both -// SetReadDeadline and SetWriteDeadline. -// -// A deadline is an absolute time after which I/O operations -// fail with a timeout (see type Error) instead of -// blocking. The deadline applies to all future and pending -// I/O, not just the immediately following call to ReadFrom or -// WriteTo. After a deadline has been exceeded, the connection -// can be refreshed by setting a deadline in the future. -// -// An idle timeout can be implemented by repeatedly extending -// the deadline after successful ReadFrom or WriteTo calls. -// -// A zero value for t means I/O operations will not time out. -func (c *UDPConn) SetDeadline(t time.Time) error { - return c.SetReadDeadline(t) -} - -// SetReadDeadline sets the deadline for future ReadFrom calls -// and any currently-blocked ReadFrom call. -// A zero value for t means ReadFrom will not time out. -func (c *UDPConn) SetReadDeadline(t time.Time) error { - var d time.Duration - var noDeadline time.Time - if t == noDeadline { - d = time.Duration(math.MaxInt64) - } else { - d = time.Until(t) - } - c.readTimer.Reset(d) - return nil -} - -// SetWriteDeadline sets the deadline for future WriteTo calls -// and any currently-blocked WriteTo call. -// Even if write times out, it may return n > 0, indicating that -// some of the data was successfully written. -// A zero value for t means WriteTo will not time out. -func (c *UDPConn) SetWriteDeadline(t time.Time) error { - // Write never blocks. - return nil -} - -// Read reads data from the connection. -// Read can be made to time out and return an Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetReadDeadline. -func (c *UDPConn) Read(b []byte) (int, error) { - n, _, err := c.ReadFrom(b) - return n, err -} - // ReadFrom reads a packet from the connection, // copying the payload into p. It returns the number of // bytes copied into p and the return address that @@ -188,40 +113,6 @@ loop: } } -// ReadFromUDP acts like ReadFrom but returns a UDPAddr. -func (c *UDPConn) ReadFromUDP(b []byte) (int, *net.UDPAddr, error) { - n, addr, err := c.ReadFrom(b) - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return -1, nil, fmt.Errorf("%w: %s", transport.ErrNotUDPAddress, addr) - } - - return n, udpAddr, err -} - -// ReadMsgUDP reads a message from c, copying the payload into b and -// the associated out-of-band data into oob. It returns the number of -// bytes copied into b, the number of bytes copied into oob, the flags -// that were set on the message and the source address of the message. -// -// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be -// used to manipulate IP-level socket options in oob. -func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) { - return -1, -1, -1, nil, transport.ErrNotSupported -} - -// Write writes data to the connection. -// Write can be made to time out and return an Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetWriteDeadline. -func (c *UDPConn) Write(b []byte) (int, error) { - if c.remAddr == nil { - return 0, errNoRemAddr - } - - return c.WriteTo(b, c.remAddr) -} - // WriteTo writes a packet with payload p to addr. // WriteTo can be made to time out and return // an Error with Timeout() == true after a fixed time limit; @@ -251,33 +142,93 @@ func (c *UDPConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { return len(p), nil } -// WriteToUDP acts like WriteTo but takes a UDPAddr. -func (c *UDPConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) { - return c.WriteTo(b, addr) +// Close closes the connection. +// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. +func (c *UDPConn) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + + if c.closed { + return errAlreadyClosed + } + c.closed = true + close(c.readCh) + + c.obs.onClosed(c.locAddr) + return nil +} + +// LocalAddr returns the local network address. +func (c *UDPConn) LocalAddr() net.Addr { + return c.locAddr } -// WriteMsgUDP writes a message to addr via c if c isn't connected, or -// to c's remote address if c is connected (in which case addr must be -// nil). The payload is copied from b and the associated out-of-band -// data is copied from oob. It returns the number of payload and -// out-of-band bytes written. +// SetDeadline sets the read and write deadlines associated +// with the connection. It is equivalent to calling both +// SetReadDeadline and SetWriteDeadline. // -// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be -// used to manipulate IP-level socket options in oob. -func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) { - return -1, -1, transport.ErrNotSupported +// A deadline is an absolute time after which I/O operations +// fail with a timeout (see type Error) instead of +// blocking. The deadline applies to all future and pending +// I/O, not just the immediately following call to ReadFrom or +// WriteTo. After a deadline has been exceeded, the connection +// can be refreshed by setting a deadline in the future. +// +// An idle timeout can be implemented by repeatedly extending +// the deadline after successful ReadFrom or WriteTo calls. +// +// A zero value for t means I/O operations will not time out. +func (c *UDPConn) SetDeadline(t time.Time) error { + return c.SetReadDeadline(t) } -// SetReadBuffer sets the size of the operating system's -// receive buffer associated with the connection. -func (c *UDPConn) SetReadBuffer(bytes int) error { - return transport.ErrNotSupported +// SetReadDeadline sets the deadline for future ReadFrom calls +// and any currently-blocked ReadFrom call. +// A zero value for t means ReadFrom will not time out. +func (c *UDPConn) SetReadDeadline(t time.Time) error { + var d time.Duration + var noDeadline time.Time + if t == noDeadline { + d = time.Duration(math.MaxInt64) + } else { + d = time.Until(t) + } + c.readTimer.Reset(d) + return nil +} + +// SetWriteDeadline sets the deadline for future WriteTo calls +// and any currently-blocked WriteTo call. +// Even if write times out, it may return n > 0, indicating that +// some of the data was successfully written. +// A zero value for t means WriteTo will not time out. +func (c *UDPConn) SetWriteDeadline(t time.Time) error { + // Write never blocks. + return nil } -// SetWriteBuffer sets the size of the operating system's -// transmit buffer associated with the connection. -func (c *UDPConn) SetWriteBuffer(bytes int) error { - return transport.ErrNotSupported +// Read reads data from the connection. +// Read can be made to time out and return an Error with Timeout() == true +// after a fixed time limit; see SetDeadline and SetReadDeadline. +func (c *UDPConn) Read(b []byte) (int, error) { + n, _, err := c.ReadFrom(b) + return n, err +} + +// RemoteAddr returns the remote network address. +func (c *UDPConn) RemoteAddr() net.Addr { + return c.remAddr +} + +// Write writes data to the connection. +// Write can be made to time out and return an Error with Timeout() == true +// after a fixed time limit; see SetDeadline and SetWriteDeadline. +func (c *UDPConn) Write(b []byte) (int, error) { + if c.remAddr == nil { + return 0, errNoRemAddr + } + + return c.WriteTo(b, c.remAddr) } func (c *UDPConn) onInboundChunk(chunk Chunk) { diff --git a/vnet/conn_test.go b/vnet/conn_test.go index 5845dd4..2099852 100644 --- a/vnet/conn_test.go +++ b/vnet/conn_test.go @@ -171,10 +171,7 @@ func TestUDPConn(t *testing.T) { var n int n, err = conn.Write(data) - if !assert.Nil(t, err, "should succeed") { - return - } - + assert.Nil(t, err, "should succeed") assert.Equal(t, len(data), n, "should match") loop: diff --git a/vnet/delay_filter_test.go b/vnet/delay_filter_test.go index d3f460b..e6874a5 100644 --- a/vnet/delay_filter_test.go +++ b/vnet/delay_filter_test.go @@ -12,22 +12,19 @@ func TestDelayFilter(t *testing.T) { t.Run("schedulesOnePacketAtATime", func(t *testing.T) { nic := newMockNIC(t) df, err := NewDelayFilter(nic, 10*time.Millisecond) - if !assert.NoError(t, err, "should succeed") { - return - } - + assert.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) defer cancel() go df.Run(ctx) - type TimestampedChunk struct { + type cchunk struct { ts time.Time c Chunk } - receiveCh := make(chan TimestampedChunk) + receiveCh := make(chan cchunk) nic.mockOnInboundChunk = func(c Chunk) { receivedAt := time.Now() - receiveCh <- TimestampedChunk{ + receiveCh <- cchunk{ ts: receivedAt, c: c, } @@ -58,28 +55,25 @@ func TestDelayFilter(t *testing.T) { t.Run("schedulesSubsequentManyPackets", func(t *testing.T) { nic := newMockNIC(t) df, err := NewDelayFilter(nic, 10*time.Millisecond) - if !assert.NoError(t, err, "should succeed") { - return - } - + assert.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) defer cancel() go df.Run(ctx) - type TimestampedChunk struct { + type cchunk struct { ts time.Time c Chunk } - receiveCh := make(chan TimestampedChunk) + receiveCh := make(chan cchunk) nic.mockOnInboundChunk = func(c Chunk) { receivedAt := time.Now() - receiveCh <- TimestampedChunk{ + receiveCh <- cchunk{ ts: receivedAt, c: c, } } - // schedule 100 chunks + // schedula 100 chunks sent := time.Now() for i := 0; i < 100; i++ { df.onInboundChunk(&chunkUDP{ @@ -88,7 +82,7 @@ func TestDelayFilter(t *testing.T) { }) } - // receive 100 chunks with delay>10ms + // receive 100 chunks with deay>10ms for i := 0; i < 100; i++ { select { case c := <-receiveCh: diff --git a/vnet/interface.go b/vnet/interface.go new file mode 100644 index 0000000..ec80c0b --- /dev/null +++ b/vnet/interface.go @@ -0,0 +1,40 @@ +package vnet + +import ( + "errors" + "net" +) + +var errNoAddressAssigned = errors.New("no address assigned") + +// See: https://play.golang.org/p/nBO9KGYEziv + +// InterfaceBase ... +type InterfaceBase net.Interface + +// Interface ... +type Interface struct { + InterfaceBase + addrs []net.Addr +} + +// NewInterface ... +func NewInterface(ifc net.Interface) *Interface { + return &Interface{ + InterfaceBase: InterfaceBase(ifc), + addrs: nil, + } +} + +// AddAddr ... +func (ifc *Interface) AddAddr(addr net.Addr) { + ifc.addrs = append(ifc.addrs, addr) +} + +// Addrs ... +func (ifc *Interface) Addrs() ([]net.Addr, error) { + if len(ifc.addrs) == 0 { + return nil, errNoAddressAssigned + } + return ifc.addrs, nil +} diff --git a/vnet/loss_filter_test.go b/vnet/loss_filter_test.go index a79439c..45153d2 100644 --- a/vnet/loss_filter_test.go +++ b/vnet/loss_filter_test.go @@ -4,18 +4,17 @@ import ( "net" "testing" - "github.com/pion/transport" "github.com/stretchr/testify/assert" ) type mockNIC struct { - mockGetInterface func(ifName string) (*transport.Interface, error) + mockGetInterface func(ifName string) (*Interface, error) mockOnInboundChunk func(c Chunk) mockGetStaticIPs func() []net.IP mockSetRouter func(r *Router) error } -func (n *mockNIC) getInterface(ifName string) (*transport.Interface, error) { +func (n *mockNIC) getInterface(ifName string) (*Interface, error) { return n.mockGetInterface(ifName) } @@ -33,19 +32,19 @@ func (n *mockNIC) setRouter(r *Router) error { func newMockNIC(t *testing.T) *mockNIC { return &mockNIC{ - mockGetInterface: func(string) (*transport.Interface, error) { - assert.Fail(t, "unexpected call to mockGetInterface") + mockGetInterface: func(string) (*Interface, error) { + assert.Fail(t, "unexpceted call to mockGetInterface") return nil, nil }, mockOnInboundChunk: func(Chunk) { - assert.Fail(t, "unexpected call to mockOnInboundChunk") + assert.Fail(t, "unexpceted call to mockOnInboundChunk") }, mockGetStaticIPs: func() []net.IP { - assert.Fail(t, "unexpected call to mockGetStaticIPs") + assert.Fail(t, "unexpceted call to mockGetStaticIPs") return nil }, mockSetRouter: func(*Router) error { - assert.Fail(t, "unexpected call to mockSetRouter") + assert.Fail(t, "unexpceted call to mockSetRouter") return nil }, } @@ -56,9 +55,7 @@ func TestLossFilter(t *testing.T) { mnic := newMockNIC(t) f, err := NewLossFilter(mnic, 100) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NoError(t, err) f.onInboundChunk(&chunkUDP{}) }) @@ -67,9 +64,7 @@ func TestLossFilter(t *testing.T) { mnic := newMockNIC(t) f, err := NewLossFilter(mnic, 0) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NoError(t, err) packets := 100 received := 0 @@ -88,9 +83,7 @@ func TestLossFilter(t *testing.T) { mnic := newMockNIC(t) f, err := NewLossFilter(mnic, 50) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NoError(t, err) packets := 1000 received := 0 diff --git a/vnet/nat.go b/vnet/nat.go index 7d88a07..22e437f 100644 --- a/vnet/nat.go +++ b/vnet/nat.go @@ -22,9 +22,8 @@ var ( // EndpointDependencyType defines a type of behavioral dependendency on the // remote endpoint's IP address or port number. This is used for the two // kinds of behaviors: -// - Port mapping behavior -// - Filtering behavior -// +// - Port mapping behavior +// - Filtering behavior // See: https://tools.ietf.org/html/rfc4787 type EndpointDependencyType uint8 @@ -59,7 +58,7 @@ type NATType struct { Mode NATMode MappingBehavior EndpointDependencyType FilteringBehavior EndpointDependencyType - Hairpinning bool // Not implemented yet + Hairpining bool // Not implemented yet PortPreservation bool // Not implemented yet MappingLifeTime time.Duration } @@ -152,7 +151,7 @@ func (n *networkAddressTranslator) translateOutbound(from Chunk) (Chunk, error) to := from.Clone() - if from.Network() == udp { + if from.Network() == udpString { if n.natType.Mode == NATModeNAT1To1 { // 1:1 NAT behavior srcAddr := from.SourceAddr().(*net.UDPAddr) //nolint:forcetypeassert @@ -239,7 +238,7 @@ func (n *networkAddressTranslator) translateInbound(from Chunk) (Chunk, error) { to := from.Clone() - if from.Network() == udp { + if from.Network() == udpString { if n.natType.Mode == NATModeNAT1To1 { // 1:1 NAT behavior dstAddr := from.DestinationAddr().(*net.UDPAddr) //nolint:forcetypeassert diff --git a/vnet/nat_test.go b/vnet/nat_test.go index 47af353..175493a 100644 --- a/vnet/nat_test.go +++ b/vnet/nat_test.go @@ -16,7 +16,7 @@ import ( const demoIP = "1.2.3.4" -func TestNATTypeDefaults(t *testing.T) { +func TestNATTypeDefauts(t *testing.T) { loggerFactory := logging.NewDefaultLoggerFactory() nat, err := newNAT(&natConfig{ natType: NATType{}, @@ -27,7 +27,7 @@ func TestNATTypeDefaults(t *testing.T) { assert.Equal(t, EndpointIndependent, nat.natType.MappingBehavior, "should match") assert.Equal(t, EndpointIndependent, nat.natType.FilteringBehavior, "should match") - assert.False(t, nat.natType.Hairpinning, "should be false") + assert.False(t, nat.natType.Hairpining, "should be false") assert.False(t, nat.natType.PortPreservation, "should be false") assert.Equal(t, defaultNATMappingLifeTime, nat.natType.MappingLifeTime, "should be false") } @@ -41,7 +41,7 @@ func TestNATMappingBehavior(t *testing.T) { natType: NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointIndependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 30 * time.Second, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -133,7 +133,7 @@ func TestNATMappingBehavior(t *testing.T) { natType: NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointAddrDependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 30 * time.Second, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -234,7 +234,7 @@ func TestNATMappingBehavior(t *testing.T) { _, err = nat.translateInbound(iec) assert.Nil(t, err, "should succeed") - // packet from different addr will be dropped (restricted-cone) + // packet from different addr will be droped (restricted-cone) //nolint:forcetypeassert iec = newChunkUDP( &net.UDPAddr{ @@ -257,7 +257,7 @@ func TestNATMappingBehavior(t *testing.T) { natType: NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointAddrPortDependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 30 * time.Second, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -356,7 +356,7 @@ func TestNATMappingBehavior(t *testing.T) { _, err = nat.translateInbound(iec) assert.NotNil(t, err, "should fail (dropped)") - // packet from different addr will be dropped (restricted-cone) + // packet from different addr will be droped (restricted-cone) //nolint:forcetypeassert iec = newChunkUDP( &net.UDPAddr{ @@ -378,7 +378,7 @@ func TestNATMappingBehavior(t *testing.T) { natType: NATType{ MappingBehavior: EndpointAddrDependent, FilteringBehavior: EndpointAddrDependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 30 * time.Second, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -448,7 +448,7 @@ func TestNATMappingBehavior(t *testing.T) { natType: NATType{ MappingBehavior: EndpointAddrPortDependent, FilteringBehavior: EndpointAddrPortDependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 30 * time.Second, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -523,7 +523,7 @@ func TestNATMappingTimeout(t *testing.T) { natType: NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointIndependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 100 * time.Millisecond, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -586,7 +586,7 @@ func TestNATMappingTimeout(t *testing.T) { natType: NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointIndependent, - Hairpinning: false, + Hairpining: false, MappingLifeTime: 100 * time.Millisecond, }, mappedIPs: []net.IP{net.ParseIP(demoIP)}, @@ -637,7 +637,7 @@ func TestNATMappingTimeout(t *testing.T) { }) } -func TestNAT1To1Behavior(t *testing.T) { +func TestNAT1To1Bahavior(t *testing.T) { loggerFactory := logging.NewDefaultLoggerFactory() log := loggerFactory.NewLogger("test") diff --git a/vnet/net.go b/vnet/net.go index e142b97..60d7028 100644 --- a/vnet/net.go +++ b/vnet/net.go @@ -9,28 +9,27 @@ import ( "strconv" "strings" "sync" - - "github.com/pion/transport" ) const ( lo0String = "lo0String" - udp = "udp" - udp4 = "udp4" + udpString = "udp" ) var ( macAddrCounter uint64 = 0xBEEFED910200 //nolint:gochecknoglobals errNoInterface = errors.New("no interface is available") + errNotFound = errors.New("not found") errUnexpectedNetwork = errors.New("unexpected network") errCantAssignRequestedAddr = errors.New("can't assign requested address") errUnknownNetwork = errors.New("unknown network") errNoRouterLinked = errors.New("no router linked") errInvalidPortNumber = errors.New("invalid port number") errUnexpectedTypeSwitchFailure = errors.New("unexpected type-switch failure") - errBindFailedFor = errors.New("bind failed for") + errBindFailerFor = errors.New("bind failed for") errEndPortLessThanStart = errors.New("end port is less than the start") errPortSpaceExhausted = errors.New("port space exhausted") + errVNetDisabled = errors.New("vnet is not enabled") ) func newMACAddress() net.HardwareAddr { @@ -40,20 +39,15 @@ func newMACAddress() net.HardwareAddr { return b[2:] } -// Net represents a local network stack equivalent to a set of layers from NIC -// up to the transport (UDP / TCP) layer. -type Net struct { - interfaces []*transport.Interface // read-only - staticIPs []net.IP // read-only - router *Router // read-only - udpConns *udpConnMap // read-only +type vNet struct { + interfaces []*Interface // read-only + staticIPs []net.IP // read-only + router *Router // read-only + udpConns *udpConnMap // read-only mutex sync.RWMutex } -// Compile-time assertion -var _ transport.Net = &Net{} - -func (v *Net) _getInterfaces() ([]*transport.Interface, error) { +func (v *vNet) _getInterfaces() ([]*Interface, error) { if len(v.interfaces) == 0 { return nil, errNoInterface } @@ -61,8 +55,7 @@ func (v *Net) _getInterfaces() ([]*transport.Interface, error) { return v.interfaces, nil } -// Interfaces returns a list of the system's network interfaces. -func (v *Net) Interfaces() ([]*transport.Interface, error) { +func (v *vNet) getInterfaces() ([]*Interface, error) { v.mutex.RLock() defer v.mutex.RUnlock() @@ -70,7 +63,7 @@ func (v *Net) Interfaces() ([]*transport.Interface, error) { } // caller must hold the mutex (read) -func (v *Net) _getInterface(ifName string) (*transport.Interface, error) { +func (v *vNet) _getInterface(ifName string) (*Interface, error) { ifs, err := v._getInterfaces() if err != nil { return nil, err @@ -81,42 +74,22 @@ func (v *Net) _getInterface(ifName string) (*transport.Interface, error) { } } - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, ifName) + return nil, fmt.Errorf("interface %s %w", ifName, errNotFound) } -func (v *Net) getInterface(ifName string) (*transport.Interface, error) { +func (v *vNet) getInterface(ifName string) (*Interface, error) { v.mutex.RLock() defer v.mutex.RUnlock() return v._getInterface(ifName) } -// InterfaceByIndex returns the interface specified by index. -// -// On Solaris, it returns one of the logical network interfaces -// sharing the logical data link; for more precision use -// InterfaceByName. -func (v *Net) InterfaceByIndex(index int) (*transport.Interface, error) { - for _, ifc := range v.interfaces { - if ifc.Index == index { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: index=%d", transport.ErrInterfaceNotFound, index) -} - -// InterfaceByName returns the interface specified by name. -func (v *Net) InterfaceByName(ifName string) (*transport.Interface, error) { - return v.getInterface(ifName) -} - // caller must hold the mutex -func (v *Net) getAllIPAddrs(ipv6 bool) []net.IP { +func (v *vNet) getAllIPAddrs(ipv6 bool) []net.IP { ips := []net.IP{} for _, ifc := range v.interfaces { - addrs, err := ifc.Addresses() + addrs, err := ifc.Addrs() if err != nil { continue } @@ -142,7 +115,7 @@ func (v *Net) getAllIPAddrs(ipv6 bool) []net.IP { return ips } -func (v *Net) setRouter(r *Router) error { +func (v *vNet) setRouter(r *Router) error { v.mutex.Lock() defer v.mutex.Unlock() @@ -150,11 +123,11 @@ func (v *Net) setRouter(r *Router) error { return nil } -func (v *Net) onInboundChunk(c Chunk) { +func (v *vNet) onInboundChunk(c Chunk) { v.mutex.Lock() defer v.mutex.Unlock() - if c.Network() == udp { + if c.Network() == udpString { if conn, ok := v.udpConns.find(c.DestinationAddr()); ok { conn.onInboundChunk(c) } @@ -162,9 +135,9 @@ func (v *Net) onInboundChunk(c Chunk) { } // caller must hold the mutex -func (v *Net) _dialUDP(network string, locAddr, remAddr *net.UDPAddr) (transport.UDPConn, error) { +func (v *vNet) _dialUDP(network string, locAddr, remAddr *net.UDPAddr) (UDPPacketConn, error) { // validate network - if network != udp && network != udp4 { + if network != udpString && network != "udp4" { return nil, fmt.Errorf("%w: %s", errUnexpectedNetwork, network) } @@ -220,12 +193,11 @@ func (v *Net) _dialUDP(network string, locAddr, remAddr *net.UDPAddr) (transport return conn, nil } -// ListenPacket announces on the local network address. -func (v *Net) ListenPacket(network string, address string) (net.PacketConn, error) { +func (v *vNet) listenPacket(network string, address string) (UDPPacketConn, error) { v.mutex.Lock() defer v.mutex.Unlock() - locAddr, err := v.ResolveUDPAddr(network, address) + locAddr, err := v.resolveUDPAddr(network, address) if err != nil { return nil, err } @@ -233,28 +205,25 @@ func (v *Net) ListenPacket(network string, address string) (net.PacketConn, erro return v._dialUDP(network, locAddr, nil) } -// ListenUDP acts like ListenPacket for UDP networks. -func (v *Net) ListenUDP(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) { +func (v *vNet) listenUDP(network string, locAddr *net.UDPAddr) (UDPPacketConn, error) { v.mutex.Lock() defer v.mutex.Unlock() return v._dialUDP(network, locAddr, nil) } -// DialUDP acts like Dial for UDP networks. -func (v *Net) DialUDP(network string, locAddr, remAddr *net.UDPAddr) (transport.UDPConn, error) { +func (v *vNet) dialUDP(network string, locAddr, remAddr *net.UDPAddr) (UDPPacketConn, error) { v.mutex.Lock() defer v.mutex.Unlock() return v._dialUDP(network, locAddr, remAddr) } -// Dial connects to the address on the named network. -func (v *Net) Dial(network string, address string) (net.Conn, error) { +func (v *vNet) dial(network string, address string) (UDPPacketConn, error) { v.mutex.Lock() defer v.mutex.Unlock() - remAddr, err := v.ResolveUDPAddr(network, address) + remAddr, err := v.resolveUDPAddr(network, address) if err != nil { return nil, err } @@ -267,15 +236,21 @@ func (v *Net) Dial(network string, address string) (net.Conn, error) { return v._dialUDP(network, locAddr, remAddr) } -// ResolveIPAddr returns an address of IP end point. -func (v *Net) ResolveIPAddr(network, address string) (*net.IPAddr, error) { - var err error +func (v *vNet) resolveUDPAddr(network, address string) (*net.UDPAddr, error) { + if network != udpString && network != "udp4" { + return nil, fmt.Errorf("%w %s", errUnknownNetwork, network) + } + + host, sPort, err := net.SplitHostPort(address) + if err != nil { + return nil, err + } // Check if host is a domain name - ip := net.ParseIP(address) + ip := net.ParseIP(host) if ip == nil { - address = strings.ToLower(address) - if address == "localhost" { + host = strings.ToLower(host) + if host == "localhost" { ip = net.IPv4(127, 0, 0, 1) } else { // host is a domain name. resolve IP address by the name @@ -283,80 +258,28 @@ func (v *Net) ResolveIPAddr(network, address string) (*net.IPAddr, error) { return nil, errNoRouterLinked } - ip, err = v.router.resolver.lookUp(address) + ip, err = v.router.resolver.lookUp(host) if err != nil { return nil, err } } } - return &net.IPAddr{ - IP: ip, - }, nil -} - -// ResolveUDPAddr returns an address of UDP end point. -func (v *Net) ResolveUDPAddr(network, address string) (*net.UDPAddr, error) { - if network != udp && network != udp4 { - return nil, fmt.Errorf("%w %s", errUnknownNetwork, network) - } - - host, sPort, err := net.SplitHostPort(address) - if err != nil { - return nil, err - } - - ipAddress, err := v.ResolveIPAddr("ip", host) - if err != nil { - return nil, err - } - port, err := strconv.Atoi(sPort) if err != nil { return nil, errInvalidPortNumber } udpAddr := &net.UDPAddr{ - IP: ipAddress.IP, - Zone: ipAddress.Zone, + IP: ip, Port: port, } return udpAddr, nil } -// ResolveTCPAddr returns an address of TCP end point. -func (v *Net) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { - if network != udp && network != "udp4" { - return nil, fmt.Errorf("%w %s", errUnknownNetwork, network) - } - - host, sPort, err := net.SplitHostPort(address) - if err != nil { - return nil, err - } - - ipAddr, err := v.ResolveIPAddr("ip", host) - if err != nil { - return nil, err - } - - port, err := strconv.Atoi(sPort) - if err != nil { - return nil, errInvalidPortNumber - } - - udpAddr := &net.TCPAddr{ - IP: ipAddr.IP, - Zone: ipAddr.Zone, - Port: port, - } - - return udpAddr, nil -} - -func (v *Net) write(c Chunk) error { - if c.Network() == udp { +func (v *vNet) write(c Chunk) error { + if c.Network() == udpString { if udp, ok := c.(*chunkUDP); ok { if c.getDestinationIP().IsLoopback() { if conn, ok := v.udpConns.find(udp.DestinationAddr()); ok { @@ -377,8 +300,8 @@ func (v *Net) write(c Chunk) error { return nil } -func (v *Net) onClosed(addr net.Addr) { - if addr.Network() == udp { +func (v *vNet) onClosed(addr net.Addr) { + if addr.Network() == udpString { //nolint:errcheck v.udpConns.delete(addr) // #nosec } @@ -388,7 +311,7 @@ func (v *Net) onClosed(addr net.Addr) { // is any IP address ("0.0.0.0" or "::"). If locIP is a non-any addr, // this method simply returns locIP. // caller must hold the mutex -func (v *Net) determineSourceIP(locIP, dstIP net.IP) net.IP { +func (v *vNet) determineSourceIP(locIP, dstIP net.IP) net.IP { if locIP != nil && !locIP.IsUnspecified() { return locIP } @@ -403,7 +326,7 @@ func (v *Net) determineSourceIP(locIP, dstIP net.IP) net.IP { return nil } - addrs, err2 := ifc.Addresses() + addrs, err2 := ifc.Addrs() if err2 != nil { return nil } @@ -439,9 +362,9 @@ func (v *Net) determineSourceIP(locIP, dstIP net.IP) net.IP { } // caller must hold the mutex -func (v *Net) hasIPAddr(ip net.IP) bool { //nolint:gocognit +func (v *vNet) hasIPAddr(ip net.IP) bool { //nolint:gocognit for _, ifc := range v.interfaces { - if addrs, err := ifc.Addresses(); err == nil { + if addrs, err := ifc.Addrs(); err == nil { for _, addr := range addrs { var locIP net.IP if ipNet, ok := addr.(*net.IPNet); ok { @@ -474,7 +397,7 @@ func (v *Net) hasIPAddr(ip net.IP) bool { //nolint:gocognit } // caller must hold the mutex -func (v *Net) allocateLocalAddr(ip net.IP, port int) error { +func (v *vNet) allocateLocalAddr(ip net.IP, port int) error { // gather local IP addresses to bind var ips []net.IP if ip.IsUnspecified() { @@ -484,7 +407,7 @@ func (v *Net) allocateLocalAddr(ip net.IP, port int) error { } if len(ips) == 0 { - return fmt.Errorf("%w %s", errBindFailedFor, ip.String()) + return fmt.Errorf("%w %s", errBindFailerFor, ip.String()) } // check if all these transport addresses are not in use @@ -496,7 +419,7 @@ func (v *Net) allocateLocalAddr(ip net.IP, port int) error { if _, ok := v.udpConns.find(addr); ok { return &net.OpError{ Op: "bind", - Net: udp, + Net: udpString, Addr: addr, Err: fmt.Errorf("bind: %w", errAddressAlreadyInUse), } @@ -507,7 +430,7 @@ func (v *Net) allocateLocalAddr(ip net.IP, port int) error { } // caller must hold the mutex -func (v *Net) assignPort(ip net.IP, start, end int) (int, error) { +func (v *vNet) assignPort(ip net.IP, start, end int) (int, error) { // choose randomly from the range between start and end (inclusive) if end < start { return -1, errEndPortLessThanStart @@ -527,10 +450,6 @@ func (v *Net) assignPort(ip net.IP, start, end int) (int, error) { return -1, errPortSpaceExhausted } -func (v *Net) getStaticIPs() []net.IP { - return v.staticIPs -} - // NetConfig is a bag of configuration parameters passed to NewNet(). type NetConfig struct { // StaticIPs is an array of static IP addresses to be assigned for this Net. @@ -542,25 +461,51 @@ type NetConfig struct { StaticIP string } -// NewNet creates an instance of a virtual network. -// +// Net represents a local network stack euivalent to a set of layers from NIC +// up to the transport (UDP / TCP) layer. +type Net struct { + v *vNet + ifs []*Interface +} + +// NewNet creates an instance of Net. +// If config is nil, the virtual network is disabled. (uses corresponding +// net.Xxxx() operations. // By design, it always have lo0 and eth0 interfaces. // The lo0 has the address 127.0.0.1 assigned by default. // IP address for eth0 will be assigned when this Net is added to a router. -func NewNet(config *NetConfig) (*Net, error) { - lo0 := transport.NewInterface(net.Interface{ +func NewNet(config *NetConfig) *Net { + if config == nil { + ifs := []*Interface{} + if orgIfs, err := net.Interfaces(); err == nil { + for _, orgIfc := range orgIfs { + ifc := NewInterface(orgIfc) + if addrs, err := orgIfc.Addrs(); err == nil { + for _, addr := range addrs { + ifc.AddAddr(addr) + } + } + + ifs = append(ifs, ifc) + } + } + + return &Net{ifs: ifs} + } + + lo0 := NewInterface(net.Interface{ Index: 1, MTU: 16384, Name: lo0String, HardwareAddr: nil, Flags: net.FlagUp | net.FlagLoopback | net.FlagMulticast, }) - lo0.AddAddress(&net.IPNet{ + lo0.AddAddr(&net.IPNet{ IP: net.ParseIP("127.0.0.1"), Mask: net.CIDRMask(8, 32), }) - eth0 := transport.NewInterface(net.Interface{ + eth0 := NewInterface(net.Interface{ Index: 2, MTU: 1500, Name: "eth0", @@ -580,36 +525,153 @@ func NewNet(config *NetConfig) (*Net, error) { } } - return &Net{ - interfaces: []*transport.Interface{lo0, eth0}, + v := &vNet{ + interfaces: []*Interface{lo0, eth0}, staticIPs: staticIPs, udpConns: newUDPConnMap(), - }, nil + } + + return &Net{ + v: v, + } +} + +// Interfaces returns a list of the system's network interfaces. +func (n *Net) Interfaces() ([]*Interface, error) { + if n.v == nil { + return n.ifs, nil + } + + return n.v.getInterfaces() +} + +// InterfaceByName returns the interface specified by name. +func (n *Net) InterfaceByName(name string) (*Interface, error) { + if n.v == nil { + for _, ifc := range n.ifs { + if ifc.Name == name { + return ifc, nil + } + } + + return nil, fmt.Errorf("interface %s %w", name, errNotFound) + } + + return n.v.getInterface(name) +} + +// ListenPacket announces on the local network address. +func (n *Net) ListenPacket(network string, address string) (net.PacketConn, error) { + if n.v == nil { + return net.ListenPacket(network, address) + } + + return n.v.listenPacket(network, address) } -// DialTCP acts like Dial for TCP networks. -func (v *Net) DialTCP(network string, laddr, raddr *net.TCPAddr) (transport.TCPConn, error) { - return nil, transport.ErrNotSupported +// ListenUDP acts like ListenPacket for UDP networks. +func (n *Net) ListenUDP(network string, locAddr *net.UDPAddr) (UDPPacketConn, error) { + if n.v == nil { + return net.ListenUDP(network, locAddr) + } + + return n.v.listenUDP(network, locAddr) } -// ListenTCP acts like Listen for TCP networks. -func (v *Net) ListenTCP(network string, laddr *net.TCPAddr) (transport.TCPListener, error) { - return nil, transport.ErrNotSupported +// Dial connects to the address on the named network. +func (n *Net) Dial(network, address string) (net.Conn, error) { + if n.v == nil { + return net.Dial(network, address) + } + + return n.v.dial(network, address) } // CreateDialer creates an instance of vnet.Dialer -func (v *Net) CreateDialer(d *net.Dialer) transport.Dialer { - return &dialer{ - dialer: d, - net: v, +func (n *Net) CreateDialer(dialer *net.Dialer) Dialer { + if n.v == nil { + return &vDialer{ + dialer: dialer, + } + } + + return &vDialer{ + dialer: dialer, + v: n.v, + } +} + +// DialUDP acts like Dial for UDP networks. +func (n *Net) DialUDP(network string, laddr, raddr *net.UDPAddr) (UDPPacketConn, error) { + if n.v == nil { + return net.DialUDP(network, laddr, raddr) + } + + return n.v.dialUDP(network, laddr, raddr) +} + +// ResolveUDPAddr returns an address of UDP end point. +func (n *Net) ResolveUDPAddr(network, address string) (*net.UDPAddr, error) { + if n.v == nil { + return net.ResolveUDPAddr(network, address) } + + return n.v.resolveUDPAddr(network, address) } -type dialer struct { +func (n *Net) getInterface(ifName string) (*Interface, error) { + if n.v == nil { + return nil, errVNetDisabled + } + + return n.v.getInterface(ifName) +} + +func (n *Net) setRouter(r *Router) error { + if n.v == nil { + return errVNetDisabled + } + + return n.v.setRouter(r) +} + +func (n *Net) onInboundChunk(c Chunk) { + if n.v == nil { + return + } + + n.v.onInboundChunk(c) +} + +func (n *Net) getStaticIPs() []net.IP { + if n.v == nil { + return nil + } + + return n.v.staticIPs +} + +// IsVirtual tests if the virtual network is enabled. +func (n *Net) IsVirtual() bool { + return n.v != nil +} + +// Dialer is identical to net.Dialer excepts that its methods +// (Dial, DialContext) are overridden to use virtual network. +// Use vnet.CreateDialer() to create an instance of this Dialer. +type Dialer interface { + Dial(network, address string) (net.Conn, error) +} + +type vDialer struct { dialer *net.Dialer - net *Net + v *vNet } -func (d *dialer) Dial(network, address string) (net.Conn, error) { - return d.net.Dial(network, address) +func (d *vDialer) Dial(network, address string) (net.Conn, error) { + if d.v == nil { + return d.dialer.Dial(network, address) + } + + return d.v.dial(network, address) } diff --git a/stdnet/net_test.go b/vnet/net_native_test.go similarity index 83% rename from stdnet/net_test.go rename to vnet/net_native_test.go index 7d6b7a3..79b60b1 100644 --- a/stdnet/net_test.go +++ b/vnet/net_native_test.go @@ -1,7 +1,7 @@ //go:build !js // +build !js -package stdnet +package vnet import ( "net" @@ -11,30 +11,22 @@ import ( "github.com/stretchr/testify/assert" ) -func TestStdNet(t *testing.T) { +func TestNetNative(t *testing.T) { log := logging.NewDefaultLoggerFactory().NewLogger("test") t.Run("Interfaces", func(t *testing.T) { - nw, err := NewNet() - if !assert.Nil(t, err, "should succeed") { - return - } - + nw := NewNet(nil) + assert.False(t, nw.IsVirtual(), "should be false") interfaces, err := nw.Interfaces() - if !assert.NoError(t, err, "should succeed") { - return - } - + assert.NoError(t, err, "should succeed") log.Debugf("interfaces: %+v", interfaces) for _, ifc := range interfaces { if ifc.Name == lo0String { - _, err := ifc.Addresses() - if !assert.NoError(t, err, "should succeed") { - return - } + _, err := ifc.Addrs() + assert.NoError(t, err, "should succeed") } - if addrs, err := ifc.Addresses(); err == nil { + if addrs, err := ifc.Addrs(); err == nil { for _, addr := range addrs { log.Debugf("[%d] %s:%s", ifc.Index, @@ -46,10 +38,7 @@ func TestStdNet(t *testing.T) { }) t.Run("ResolveUDPAddr", func(t *testing.T) { - nw, err := NewNet() - if !assert.Nil(t, err, "should succeed") { - return - } + nw := NewNet(nil) udpAddr, err := nw.ResolveUDPAddr(udpString, "localhost:1234") if !assert.NoError(t, err, "should succeed") { @@ -60,10 +49,7 @@ func TestStdNet(t *testing.T) { }) t.Run("ListenPacket", func(t *testing.T) { - nw, err := NewNet() - if !assert.Nil(t, err, "should succeed") { - return - } + nw := NewNet(nil) conn, err := nw.ListenPacket(udpString, "127.0.0.1:0") if !assert.NoError(t, err, "should succeed") { @@ -79,10 +65,7 @@ func TestStdNet(t *testing.T) { }) t.Run("ListenUDP random port", func(t *testing.T) { - nw, err := NewNet() - if !assert.Nil(t, err, "should succeed") { - return - } + nw := NewNet(nil) srcAddr := &net.UDPAddr{ IP: net.ParseIP("127.0.0.1"), @@ -97,8 +80,7 @@ func TestStdNet(t *testing.T) { }) t.Run("Dial (UDP)", func(t *testing.T) { - nw, err := NewNet() - assert.Nil(t, err, "should succeed") + nw := NewNet(nil) conn, err := nw.Dial(udpString, "127.0.0.1:1234") assert.NoError(t, err, "should succeed") @@ -116,8 +98,7 @@ func TestStdNet(t *testing.T) { }) t.Run("DialUDP", func(t *testing.T) { - nw, err := NewNet() - assert.Nil(t, err, "should succeed") + nw := NewNet(nil) locAddr := &net.UDPAddr{ IP: net.IPv4(127, 0, 0, 1), @@ -145,8 +126,7 @@ func TestStdNet(t *testing.T) { }) t.Run("UDPLoopback", func(t *testing.T) { - nw, err := NewNet() - assert.Nil(t, err, "should succeed") + nw := NewNet(nil) conn, err := nw.ListenPacket(udpString, "127.0.0.1:0") assert.NoError(t, err, "should succeed") @@ -166,8 +146,7 @@ func TestStdNet(t *testing.T) { }) t.Run("Dialer", func(t *testing.T) { - nw, err := NewNet() - assert.Nil(t, err, "should succeed") + nw := NewNet(nil) dialer := nw.CreateDialer(&net.Dialer{ LocalAddr: &net.UDPAddr{ @@ -192,7 +171,7 @@ func TestStdNet(t *testing.T) { }) t.Run("Unexpected operations", func(t *testing.T) { - // For portability of test, find a name of loopback interface name first + // For portability of test, find a name of loopack interface name first var loName string ifs, err := net.Interfaces() assert.NoError(t, err, "should succeed") @@ -203,17 +182,31 @@ func TestStdNet(t *testing.T) { } } - nw, err := NewNet() - assert.Nil(t, err, "should succeed") + nw := NewNet(nil) if len(loName) > 0 { // InterfaceByName ifc, err2 := nw.InterfaceByName(loName) assert.NoError(t, err2, "should succeed") assert.Equal(t, loName, ifc.Name, "should match") + + // getInterface + _, err2 = nw.getInterface(loName) + assert.Error(t, err2, "should fail") } _, err = nw.InterfaceByName("foo0") assert.Error(t, err, "should fail") + + // setRouter + err = nw.setRouter(nil) + assert.Error(t, err, "should fail") + + // onInboundChunk (shouldn't crash) + nw.onInboundChunk(nil) + + // getStaticIPs + ips := nw.getStaticIPs() + assert.Nil(t, ips, "should be nil") }) } diff --git a/vnet/net_test.go b/vnet/net_test.go index 1ed3d3b..3fad686 100644 --- a/vnet/net_test.go +++ b/vnet/net_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/pion/logging" - "github.com/pion/transport" "github.com/stretchr/testify/assert" ) @@ -14,17 +13,15 @@ func TestNetVirtual(t *testing.T) { loggerFactory := logging.NewDefaultLoggerFactory() log := logging.NewDefaultLoggerFactory().NewLogger("test") - t.Run("tnet.Interfaces", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + t.Run("Interfaces", func(t *testing.T) { + nw := NewNet(&NetConfig{}) + assert.True(t, nw.IsVirtual(), "should be true") - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - for _, ifc := range intfs { + for _, ifc := range interfaces { switch ifc.Name { case lo0String: assert.Equal(t, 1, ifc.Index, "Index mismatch") @@ -38,7 +35,7 @@ func TestNetVirtual(t *testing.T) { ifc.Flags, "Flags mismatch") - addrs, err := ifc.Addresses() + addrs, err := ifc.Addrs() assert.NoError(t, err, "should succeed") assert.Equal(t, 1, len(addrs), "should be one address") case "eth0": @@ -50,13 +47,13 @@ func TestNetVirtual(t *testing.T) { ifc.Flags, "Flags mismatch") - _, err := ifc.Addresses() + _, err := ifc.Addrs() assert.NotNil(t, err, "should fail") default: - assert.Fail(t, "unknown tnet.Interface: %v", ifc.Name) + assert.Fail(t, "unknown interface: %v", ifc.Name) } - if addrs, err := ifc.Addresses(); err == nil { + if addrs, err := ifc.Addrs(); err == nil { for _, addr := range addrs { log.Debugf("[%d] %s:%s", ifc.Index, @@ -67,17 +64,14 @@ func TestNetVirtual(t *testing.T) { } }) - t.Run("tnet.InterfaceByName", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + t.Run("InterfaceByName", func(t *testing.T) { + nw := NewNet(&NetConfig{}) - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - var ifc *transport.Interface + var ifc *Interface ifc, err = nw.InterfaceByName(lo0String) assert.NoError(t, err, "should succeed") @@ -93,7 +87,7 @@ func TestNetVirtual(t *testing.T) { ifc.Flags, "Flags mismatch") - addrs, err2 := ifc.Addresses() + addrs, err2 := ifc.Addrs() assert.NoError(t, err2, "should succeed") assert.Equal(t, 1, len(addrs), "should be one address") } @@ -108,7 +102,7 @@ func TestNetVirtual(t *testing.T) { ifc.Flags, "Flags mismatch") - _, err = ifc.Addresses() + _, err = ifc.Addrs() assert.NotNil(t, err, "should fail") _, err = nw.InterfaceByName("foo0") @@ -116,55 +110,49 @@ func TestNetVirtual(t *testing.T) { }) t.Run("hasIPAddr", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - var ifc *transport.Interface + var ifc *Interface ifc, err = nw.InterfaceByName("eth0") assert.NoError(t, err, "should succeed") - ifc.AddAddress(&net.IPNet{ + ifc.AddAddr(&net.IPNet{ IP: net.ParseIP("10.1.2.3"), Mask: net.CIDRMask(24, 32), }) - _, err = ifc.Addresses() + _, err = ifc.Addrs() assert.NoError(t, err, "should succeed") - assert.True(t, nw.hasIPAddr(net.ParseIP("127.0.0.1")), + assert.True(t, nw.v.hasIPAddr(net.ParseIP("127.0.0.1")), "the IP addr should exist") - assert.True(t, nw.hasIPAddr(net.ParseIP("10.1.2.3")), + assert.True(t, nw.v.hasIPAddr(net.ParseIP("10.1.2.3")), "the IP addr should exist") - assert.False(t, nw.hasIPAddr(net.ParseIP("192.168.1.1")), + assert.False(t, nw.v.hasIPAddr(net.ParseIP("192.168.1.1")), "the IP addr should NOT exist") }) t.Run("getAllIPAddrs", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - var ifc *transport.Interface + var ifc *Interface ifc, err = nw.InterfaceByName("eth0") assert.NoError(t, err, "should succeed") - ifc.AddAddress(&net.IPNet{ + ifc.AddAddr(&net.IPNet{ IP: net.ParseIP("10.1.2.3"), Mask: net.CIDRMask(24, 32), }) - ips := nw.getAllIPAddrs(false) + ips := nw.v.getAllIPAddrs(false) assert.Equal(t, 2, len(ips), "should match") for _, ip := range ips { @@ -173,35 +161,32 @@ func TestNetVirtual(t *testing.T) { }) t.Run("assignPort()", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) addr := demoIP start := 1000 end := 1002 space := end + 1 - start - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - var ifc *transport.Interface + var ifc *Interface ifc, err = nw.InterfaceByName("eth0") assert.NoError(t, err, "should succeed") - ifc.AddAddress(&net.IPNet{ + ifc.AddAddr(&net.IPNet{ IP: net.ParseIP(addr), Mask: net.CIDRMask(24, 32), }) // attempt to assign port with start > end should fail - _, err = nw.assignPort(net.ParseIP(addr), 3000, 2999) + _, err = nw.v.assignPort(net.ParseIP(addr), 3000, 2999) assert.NotNil(t, err, "should fail") for i := 0; i < space; i++ { - port, err2 := nw.assignPort(net.ParseIP(addr), start, end) + port, err2 := nw.v.assignPort(net.ParseIP(addr), start, end) assert.NoError(t, err2, "should succeed") log.Debugf("[%d] got port: %d", i, port) @@ -210,32 +195,29 @@ func TestNetVirtual(t *testing.T) { Port: port, }, nil, &myConnObserver{}) assert.NoError(t, err2, "should succeed") - err2 = nw.udpConns.insert(conn) + err2 = nw.v.udpConns.insert(conn) assert.NoError(t, err2, "should succeed") } - assert.Equal(t, space, nw.udpConns.size(), "should match") + assert.Equal(t, space, nw.v.udpConns.size(), "should match") // attempt to assign again should fail - _, err = nw.assignPort(net.ParseIP(addr), start, end) + _, err = nw.v.assignPort(net.ParseIP(addr), start, end) assert.NotNil(t, err, "should fail") }) t.Run("determineSourceIP()", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - intfs, err := nw.Interfaces() - assert.Equal(t, 2, len(intfs), "should be one tnet.Interface") + interfaces, err := nw.Interfaces() + assert.Equal(t, 2, len(interfaces), "should be one interface") assert.NoError(t, err, "should succeed") - var ifc *transport.Interface + var ifc *Interface ifc, err = nw.InterfaceByName("eth0") assert.NoError(t, err, "should succeed") - ifc.AddAddress(&net.IPNet{ + ifc.AddAddr(&net.IPNet{ IP: net.ParseIP(demoIP), Mask: net.CIDRMask(24, 32), }) @@ -243,7 +225,7 @@ func TestNetVirtual(t *testing.T) { // Any IP turned into non-loopback IP anyIP := net.ParseIP("0.0.0.0") dstIP := net.ParseIP("27.1.7.135") - srcIP := nw.determineSourceIP(anyIP, dstIP) + srcIP := nw.v.determineSourceIP(anyIP, dstIP) log.Debugf("anyIP: %s => %s", anyIP.String(), srcIP.String()) assert.NotNil(t, srcIP, "shouldn't be nil") assert.Equal(t, srcIP.String(), demoIP, "use non-loopback IP") @@ -251,7 +233,7 @@ func TestNetVirtual(t *testing.T) { // Any IP turned into loopback IP anyIP = net.ParseIP("0.0.0.0") dstIP = net.ParseIP("127.0.0.2") - srcIP = nw.determineSourceIP(anyIP, dstIP) + srcIP = nw.v.determineSourceIP(anyIP, dstIP) log.Debugf("anyIP: %s => %s", anyIP.String(), srcIP.String()) assert.NotNil(t, srcIP, "shouldn't be nil") assert.Equal(t, srcIP.String(), "127.0.0.1", "use loopback IP") @@ -259,19 +241,16 @@ func TestNetVirtual(t *testing.T) { // Non any IP won't change anyIP = net.ParseIP(demoIP) dstIP = net.ParseIP("127.0.0.2") - srcIP = nw.determineSourceIP(anyIP, dstIP) + srcIP = nw.v.determineSourceIP(anyIP, dstIP) log.Debugf("anyIP: %s => %s", anyIP.String(), srcIP.String()) assert.NotNil(t, srcIP, "shouldn't be nil") assert.True(t, srcIP.Equal(anyIP), "IP change") }) t.Run("ResolveUDPAddr", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - udpAddr, err := nw.ResolveUDPAddr(udp, "localhost:1234") + udpAddr, err := nw.ResolveUDPAddr(udpString, "localhost:1234") if !assert.NoError(t, err, "should succeed") { return } @@ -280,12 +259,9 @@ func TestNetVirtual(t *testing.T) { }) t.Run("UDPLoopback", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - conn, err := nw.ListenPacket(udp, "127.0.0.1:0") + conn, err := nw.ListenPacket(udpString, "127.0.0.1:0") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() msg := "PING!" @@ -300,93 +276,78 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, msg, string(buf[:n]), "should match") assert.Equal(t, laddr.(*net.UDPAddr).String(), addr.(*net.UDPAddr).String(), "should match") //nolint:forcetypeassert - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("ListenPacket random port", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - conn, err := nw.ListenPacket(udp, "127.0.0.1:0") + conn, err := nw.ListenPacket(udpString, "127.0.0.1:0") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr().String() log.Debugf("laddr: %s", laddr) - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("ListenPacket specific port", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - conn, err := nw.ListenPacket(udp, "127.0.0.1:50916") + conn, err := nw.ListenPacket(udpString, "127.0.0.1:50916") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr().String() assert.Equal(t, "127.0.0.1:50916", laddr, "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("ListenUDP random port", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) srcAddr := &net.UDPAddr{ IP: net.ParseIP("127.0.0.1"), } - conn, err := nw.ListenUDP(udp, srcAddr) + conn, err := nw.ListenUDP(udpString, srcAddr) assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr().String() log.Debugf("laddr: %s", laddr) - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("ListenUDP specific port", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) srcAddr := &net.UDPAddr{ IP: net.ParseIP("127.0.0.1"), Port: 60916, } - conn, err := nw.ListenUDP(udp, srcAddr) + conn, err := nw.ListenUDP(udpString, srcAddr) assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr().String() assert.Equal(t, "127.0.0.1:60916", laddr, "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("Dial (UDP) lo0", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - conn, err := nw.Dial(udp, "127.0.0.1:1234") + conn, err := nw.Dial(udpString, "127.0.0.1:1234") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -398,9 +359,9 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, "127.0.0.1", laddr.(*net.UDPAddr).IP.String(), "should match") //nolint:forcetypeassert assert.True(t, laddr.(*net.UDPAddr).Port != 0, "should match") //nolint:forcetypeassert assert.Equal(t, "127.0.0.1:1234", raddr.String(), "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("Dial (UDP) eth0", func(t *testing.T) { @@ -409,15 +370,13 @@ func TestNetVirtual(t *testing.T) { LoggerFactory: loggerFactory, }) assert.NoError(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) assert.NoError(t, wan.AddNet(nw), "should succeed") - conn, err := nw.Dial(udp, "27.3.4.5:1234") + conn, err := nw.Dial(udpString, "27.3.4.5:1234") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -429,16 +388,13 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, "1.2.3.1", laddr.(*net.UDPAddr).IP.String(), "should match") //nolint:forcetypeassert assert.True(t, laddr.(*net.UDPAddr).Port != 0, "should match") //nolint:forcetypeassert assert.Equal(t, "27.3.4.5:1234", raddr.String(), "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("DialUDP", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) locAddr := &net.UDPAddr{ IP: net.IPv4(127, 0, 0, 1), @@ -450,7 +406,7 @@ func TestNetVirtual(t *testing.T) { Port: 1234, } - conn, err := nw.DialUDP(udp, locAddr, remAddr) + conn, err := nw.DialUDP(udpString, locAddr, remAddr) assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -462,9 +418,9 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, "127.0.0.1", laddr.(*net.UDPAddr).IP.String(), "should match") //nolint:forcetypeassert assert.True(t, laddr.(*net.UDPAddr).Port != 0, "should match") //nolint:forcetypeassert assert.Equal(t, "127.0.0.1:1234", raddr.String(), "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("Resolver", func(t *testing.T) { @@ -472,21 +428,17 @@ func TestNetVirtual(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NoError(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") err = wan.AddHost("test.pion.ly", "30.31.32.33") assert.NoError(t, err, "should succeed") - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) assert.NoError(t, wan.AddNet(nw), "should succeed") - conn, err := nw.Dial(udp, "test.pion.ly:1234") + conn, err := nw.Dial(udpString, "test.pion.ly:1234") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -498,18 +450,15 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, "1.2.3.1", laddr.(*net.UDPAddr).IP.String(), "should match") //nolint:forcetypeassert assert.True(t, laddr.(*net.UDPAddr).Port != 0, "should match") //nolint:forcetypeassert assert.Equal(t, "30.31.32.33:1234", raddr.String(), "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("Loopback", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) - conn, err := nw.ListenPacket(udp, "127.0.0.1:50916") + conn, err := nw.ListenPacket(udpString, "127.0.0.1:50916") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -550,7 +499,7 @@ func TestNetVirtual(t *testing.T) { close(doneCh) }() - nw.onInboundChunk(c) + nw.v.onInboundChunk(c) loop: for { @@ -563,7 +512,7 @@ func TestNetVirtual(t *testing.T) { } } - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") assert.True(t, hasReceived, "should have received data") }) @@ -576,21 +525,16 @@ func TestNetVirtual(t *testing.T) { LoggerFactory: loggerFactory, }) assert.NoError(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") - net1, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + net1 := NewNet(&NetConfig{}) err = wan.AddNet(net1) assert.NoError(t, err, "should succeed") ip1, err := getIPAddr(net1) assert.NoError(t, err, "should succeed") - net2, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + net2 := NewNet(&NetConfig{}) err = wan.AddNet(net2) assert.NoError(t, err, "should succeed") @@ -598,13 +542,13 @@ func TestNetVirtual(t *testing.T) { assert.NoError(t, err, "should succeed") conn1, err := net1.ListenPacket( - udp, + udpString, fmt.Sprintf("%s:%d", ip1, 1234), ) assert.NoError(t, err, "should succeed") conn2, err := net2.ListenPacket( - udp, + udpString, fmt.Sprintf("%s:%d", ip2, 5678), ) assert.NoError(t, err, "should succeed") @@ -675,10 +619,7 @@ func TestNetVirtual(t *testing.T) { }) t.Run("Dialer", func(t *testing.T) { - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nw := NewNet(&NetConfig{}) dialer := nw.CreateDialer(&net.Dialer{ LocalAddr: &net.UDPAddr{ @@ -687,7 +628,7 @@ func TestNetVirtual(t *testing.T) { }, }) - conn, err := dialer.Dial(udp, "127.0.0.1:1234") + conn, err := dialer.Dial(udpString, "127.0.0.1:1234") assert.NoError(t, err, "should succeed") laddr := conn.LocalAddr() @@ -699,9 +640,9 @@ func TestNetVirtual(t *testing.T) { assert.Equal(t, "127.0.0.1", laddr.(*net.UDPAddr).IP.String(), "should match") //nolint:forcetypeassert assert.True(t, laddr.(*net.UDPAddr).Port != 0, "should match") //nolint:forcetypeassert assert.Equal(t, "127.0.0.1:1234", raddr.String(), "should match") - assert.Equal(t, 1, nw.udpConns.size(), "should match") + assert.Equal(t, 1, nw.v.udpConns.size(), "should match") assert.NoError(t, conn.Close(), "should succeed") - assert.Equal(t, 0, nw.udpConns.size(), "should match") + assert.Equal(t, 0, nw.v.udpConns.size(), "should match") }) t.Run("Two IPs on a NIC", func(t *testing.T) { @@ -712,19 +653,15 @@ func TestNetVirtual(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NoError(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") - net1, err := NewNet(&NetConfig{ + net1 := NewNet(&NetConfig{ StaticIPs: []string{ demoIP, "1.2.3.5", }, }) - if !assert.NoError(t, err, "should succeed") { - return - } err = wan.AddNet(net1) assert.NoError(t, err, "should succeed") @@ -733,10 +670,10 @@ func TestNetVirtual(t *testing.T) { err = wan.Start() assert.NoError(t, err, "should succeed") - conn1, err := net1.ListenPacket(udp, "1.2.3.4:1234") + conn1, err := net1.ListenPacket(udpString, "1.2.3.4:1234") assert.NoError(t, err, "should succeed") - conn2, err := net1.ListenPacket(udp, "1.2.3.5:1234") + conn2, err := net1.ListenPacket(udpString, "1.2.3.5:1234") assert.NoError(t, err, "should succeed") conn1RcvdCh := make(chan bool) diff --git a/vnet/resolver.go b/vnet/resolver.go index b29c085..e5166e3 100644 --- a/vnet/resolver.go +++ b/vnet/resolver.go @@ -11,7 +11,7 @@ import ( var ( errHostnameEmpty = errors.New("host name must not be empty") - errFailedToParseIPAddr = errors.New("failed to parse IP address") + errFailedtoParseIPAddr = errors.New("failed to parse IP address") ) type resolverConfig struct { @@ -53,7 +53,7 @@ func (r *resolver) addHost(name string, ipAddr string) error { } ip := net.ParseIP(ipAddr) if ip == nil { - return fmt.Errorf("%w \"%s\"", errFailedToParseIPAddr, ipAddr) + return fmt.Errorf("%w \"%s\"", errFailedtoParseIPAddr, ipAddr) } r.hosts[name] = ip return nil diff --git a/vnet/router.go b/vnet/router.go index 2b09ed4..9e44f9e 100644 --- a/vnet/router.go +++ b/vnet/router.go @@ -11,7 +11,6 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/transport" ) const ( @@ -64,9 +63,9 @@ type RouterConfig struct { LoggerFactory logging.LoggerFactory } -// NIC is a network interface controller that interfaces Router +// NIC is a nework inerface controller that interfaces Router type NIC interface { - getInterface(ifName string) (*transport.Interface, error) + getInterface(ifName string) (*Interface, error) onInboundChunk(c Chunk) getStaticIPs() []net.IP setRouter(r *Router) error @@ -79,7 +78,7 @@ type ChunkFilter func(c Chunk) bool // Router ... type Router struct { name string // read-only - interfaces []*transport.Interface // read-only + interfaces []*Interface // read-only ipv4Net *net.IPNet // read-only staticIPs []net.IP // read-only staticLocalIPs map[string]net.IP // read-only, @@ -117,17 +116,17 @@ func NewRouter(config *RouterConfig) (*Router, error) { } // set up network interface, lo0 - lo0 := transport.NewInterface(net.Interface{ + lo0 := NewInterface(net.Interface{ Index: 1, MTU: 16384, Name: lo0String, HardwareAddr: nil, Flags: net.FlagUp | net.FlagLoopback | net.FlagMulticast, }) - lo0.AddAddress(&net.IPAddr{IP: net.ParseIP("127.0.0.1"), Zone: ""}) + lo0.AddAddr(&net.IPAddr{IP: net.ParseIP("127.0.0.1"), Zone: ""}) // set up network interface, eth0 - eth0 := transport.NewInterface(net.Interface{ + eth0 := NewInterface(net.Interface{ Index: 2, MTU: 1500, Name: "eth0", @@ -178,7 +177,7 @@ func NewRouter(config *RouterConfig) (*Router, error) { return &Router{ name: name, - interfaces: []*transport.Interface{lo0, eth0}, + interfaces: []*Interface{lo0, eth0}, ipv4Net: ipv4Net, staticIPs: staticIPs, staticLocalIPs: staticLocalIPs, @@ -195,7 +194,7 @@ func NewRouter(config *RouterConfig) (*Router, error) { } // caller must hold the mutex -func (r *Router) getInterfaces() ([]*transport.Interface, error) { +func (r *Router) getInterfaces() ([]*Interface, error) { if len(r.interfaces) == 0 { return nil, fmt.Errorf("%w is available", errNoInterface) } @@ -203,7 +202,7 @@ func (r *Router) getInterfaces() ([]*transport.Interface, error) { return r.interfaces, nil } -func (r *Router) getInterface(ifName string) (*transport.Interface, error) { +func (r *Router) getInterface(ifName string) (*Interface, error) { r.mutex.RLock() defer r.mutex.RUnlock() @@ -217,7 +216,7 @@ func (r *Router) getInterface(ifName string) (*transport.Interface, error) { } } - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, ifName) + return nil, fmt.Errorf("interface %s %w", ifName, errNotFound) } // Start ... @@ -317,7 +316,7 @@ func (r *Router) addNIC(nic NIC) error { return fmt.Errorf("%w: %s", errStaticIPisBeyondSubnet, r.ipv4Net.String()) } - ifc.AddAddress(&net.IPNet{ + ifc.AddAddr(&net.IPNet{ IP: ip, Mask: r.ipv4Net.Mask, }) @@ -332,7 +331,7 @@ func (r *Router) addNIC(nic NIC) error { return nil } -// AddRouter adds a child Router. +// AddRouter adds a chile Router. func (r *Router) AddRouter(router *Router) error { r.mutex.Lock() defer r.mutex.Unlock() @@ -483,7 +482,7 @@ func (r *Router) processChunks() (time.Duration, error) { dstIP := c.getDestinationIP() - // check if the destination is in our subnet + // check if the desination is in our subnet if r.ipv4Net.Contains(dstIP) { // search for the destination NIC var nic NIC @@ -521,7 +520,7 @@ func (r *Router) processChunks() (time.Duration, error) { //nolint:godox /* FIXME: this implementation would introduce a duplicate packet! - if r.nat.natType.Hairpinning { + if r.nat.natType.Hairpining { hairpinned, err := r.nat.translateInbound(toParent) if err != nil { r.log.Warnf("[%s] %s", r.name, err.Error()) @@ -554,15 +553,14 @@ func (r *Router) setRouter(parent *Router) error { return err } - addrs, _ := ifc.Addresses() - if len(addrs) == 0 { + if len(ifc.addrs) == 0 { return errNoIPAddrEth0 } mappedIPs := []net.IP{} localIPs := []net.IP{} - for _, ifcAddr := range addrs { + for _, ifcAddr := range ifc.addrs { var ip net.IP switch addr := ifcAddr.(type) { case *net.IPNet: @@ -588,7 +586,7 @@ func (r *Router) setRouter(parent *Router) error { r.natType = &NATType{ MappingBehavior: EndpointIndependent, FilteringBehavior: EndpointAddrPortDependent, - Hairpinning: false, + Hairpining: false, PortPreservation: false, MappingLifeTime: 30 * time.Second, } diff --git a/vnet/router_test.go b/vnet/router_test.go index 8661e96..91a9698 100644 --- a/vnet/router_test.go +++ b/vnet/router_test.go @@ -14,7 +14,7 @@ import ( var errNoAddress = errors.New("there must be one address") type dummyNIC struct { - *Net + Net onInboundChunkHandler func(Chunk) } @@ -29,7 +29,7 @@ func getIPAddr(n NIC) (string, error) { return "", err } - addrs, err := eth0.Addresses() + addrs, err := eth0.Addrs() if err != nil { return "", err } @@ -50,10 +50,8 @@ func TestRouterStandalone(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") assert.Equal(t, "1.2.3.0", r.ipv4Net.IP.String(), "ip should match") assert.Equal(t, "ffffff00", r.ipv4Net.Mask.String(), "mask should match") }) @@ -63,9 +61,7 @@ func TestRouterStandalone(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") for i := 1; i < 255; i++ { ip, err2 := r.assignIPAddress() @@ -85,23 +81,18 @@ func TestRouterStandalone(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") - nic, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + nic := NewNet(&NetConfig{}) + assert.NotNil(t, nic, "should succeed") err = r.AddNet(nic) assert.Nil(t, err, "should succeed") // Now, eth0 must have one address assigned - eth0, err := nic.getInterface("eth0") + eth0, err := nic.v.getInterface("eth0") assert.Nil(t, err, "should succeed") - - addrs, err := eth0.Addresses() + addrs, err := eth0.Addrs() assert.Nil(t, err, "should succeed") assert.Equal(t, 1, len(addrs), "should match") assert.Equal(t, "ip+net", addrs[0].Network(), "should match") @@ -114,9 +105,7 @@ func TestRouterStandalone(t *testing.T) { CIDR: "0.0.0.0/0", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") r2, err := NewRouter(&RouterConfig{ CIDR: "192.168.0.0/24", @@ -126,9 +115,7 @@ func TestRouterStandalone(t *testing.T) { LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") err = r1.AddNet(r2) assert.Nil(t, err, "should succeed") @@ -144,21 +131,17 @@ func TestRouterStandalone(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") nic := make([]*dummyNIC, 2) ip := make([]*net.UDPAddr, 2) for i := 0; i < 2; i++ { - anic, netErr := NewNet(&NetConfig{}) - if !assert.NoError(t, netErr, "should succeed") { - return - } + anic := NewNet(&NetConfig{}) + assert.NotNil(t, anic, "should succeed") nic[i] = &dummyNIC{ - Net: anic, + Net: *anic, } err2 := r.AddNet(nic[i]) @@ -167,7 +150,7 @@ func TestRouterStandalone(t *testing.T) { // Now, eth0 must have one address assigned eth0, err2 := nic[i].getInterface("eth0") assert.Nil(t, err2, "should succeed") - addrs, err2 := eth0.Addresses() + addrs, err2 := eth0.Addrs() assert.Nil(t, err2, "should succeed") assert.Equal(t, 1, len(addrs), "should match") //nolint:forcetypeassert @@ -206,21 +189,17 @@ func TestRouterStandalone(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") nic := make([]*dummyNIC, 2) ip := make([]*net.UDPAddr, 2) for i := 0; i < 2; i++ { - anic, netErr := NewNet(&NetConfig{}) - if !assert.NoError(t, netErr, "should succeed") { - return - } + anic := NewNet(&NetConfig{}) + assert.NotNil(t, anic, "should succeed") nic[i] = &dummyNIC{ - Net: anic, + Net: *anic, } err2 := r.AddNet(nic[i]) @@ -229,7 +208,7 @@ func TestRouterStandalone(t *testing.T) { // Now, eth0 must have one address assigned eth0, err2 := nic[i].getInterface("eth0") assert.Nil(t, err2, "should succeed") - addrs, err2 := eth0.Addresses() + addrs, err2 := eth0.Addrs() assert.Nil(t, err2, "should succeed") assert.Equal(t, 1, len(addrs), "should match") //nolint:forcetypeassert @@ -287,7 +266,6 @@ func TestRouterStandalone(t *testing.T) { err = r.Stop() assert.Nil(t, err, "should succeed") - assert.Equal(t, int32(0), atomic.LoadInt32(&nCbs0), "should be zero") assert.Equal(t, int32(1), atomic.LoadInt32(&nCbs1), "should be zero") assert.Equal(t, byte(2), seq, "should be the last chunk") @@ -309,21 +287,17 @@ func TestRouterDelay(t *testing.T) { MaxJitter: maxJitter, LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") nic := make([]*dummyNIC, 2) ip := make([]*net.UDPAddr, 2) for i := 0; i < 2; i++ { - anic, netErr := NewNet(&NetConfig{}) - if !assert.NoError(t, netErr, "should succeed") { - return - } + anic := NewNet(&NetConfig{}) + assert.NotNil(t, anic, "should succeed") nic[i] = &dummyNIC{ - Net: anic, + Net: *anic, } err2 := r.AddNet(nic[i]) @@ -332,7 +306,7 @@ func TestRouterDelay(t *testing.T) { // Now, eth0 must have one address assigned eth0, err2 := nic[i].getInterface("eth0") assert.Nil(t, err2, "should succeed") - addrs, err2 := eth0.Addresses() + addrs, err2 := eth0.Addrs() assert.Nil(t, err2, "should succeed") assert.Equal(t, 1, len(addrs), "should match") //nolint:forcetypeassert @@ -400,17 +374,11 @@ func TestRouterOneChild(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } - - nw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") wanNet := &dummyNIC{ - Net: nw, + Net: *NewNet(&NetConfig{}), } err = wan.AddNet(wanNet) @@ -419,7 +387,6 @@ func TestRouterOneChild(t *testing.T) { // Now, eth0 must have one address assigned wanIP, err := getIPAddr(wanNet) assert.Nil(t, err, "should succeed") - log.Debugf("wanIP: %s", wanIP) // LAN @@ -427,17 +394,11 @@ func TestRouterOneChild(t *testing.T) { CIDR: "192.168.0.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } - - lnw, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") + assert.NotNil(t, lan, "should succeed") lanNet := &dummyNIC{ - Net: lnw, + Net: *NewNet(&NetConfig{}), } err = lan.AddNet(lanNet) assert.Nil(t, err, "should succeed") @@ -448,9 +409,7 @@ func TestRouterOneChild(t *testing.T) { log.Debugf("lanIP: %s", lanIP) err = wan.AddRouter(lan) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") lanNet.onInboundChunkHandler = func(c Chunk) { log.Debugf("lanNet received: %s", c.String()) @@ -510,9 +469,8 @@ func TestRouterStaticIPs(t *testing.T) { }, LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") + assert.NotNil(t, lan, "should succeed") assert.Equal(t, 3, len(lan.staticIPs), "should be 3") assert.Equal(t, "1.2.3.1", lan.staticIPs[0].String(), "should match") @@ -531,9 +489,8 @@ func TestRouterStaticIPs(t *testing.T) { StaticIP: demoIP, LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") + assert.NotNil(t, lan, "should succeed") assert.Equal(t, 4, len(lan.staticIPs), "should be 4") assert.Equal(t, "1.2.3.1", lan.staticIPs[0].String(), "should match") @@ -553,6 +510,7 @@ func TestRouterStaticIPs(t *testing.T) { LoggerFactory: loggerFactory, }) assert.NoError(t, err, "should succeed") + assert.NotNil(t, lan, "should succeed") assert.Equal(t, 3, len(lan.staticIPs), "should be 3") assert.Equal(t, "1.2.3.1", lan.staticIPs[0].String(), "should match") @@ -605,7 +563,12 @@ func TestRouterStaticIPs(t *testing.T) { CIDR: "0.0.0.0/0", LoggerFactory: loggerFactory, }) - assert.NoError(t, err, "should succeed") + if !assert.NoError(t, err, "should succeed") { + return + } + if !assert.NotNil(t, wan, "should succeed") { + return + } lan, err := NewRouter(&RouterConfig{ CIDR: "192.168.0.0/24", @@ -619,7 +582,12 @@ func TestRouterStaticIPs(t *testing.T) { }, LoggerFactory: loggerFactory, }) - assert.NoError(t, err, "should succeed") + if !assert.NoError(t, err, "should succeed") { + return + } + if !assert.NotNil(t, lan, "should succeed") { + return + } err = wan.AddRouter(lan) if !assert.NoError(t, err, "should succeed") { @@ -650,9 +618,7 @@ func TestRouterFailures(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") err = r.Stop() assert.Error(t, err, "should fail") @@ -663,18 +629,14 @@ func TestRouterFailures(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") - nic, err := NewNet(&NetConfig{ + nic := NewNet(&NetConfig{ StaticIPs: []string{ "5.6.7.8", // out of parent router'c CIDR }, }) - if !assert.NoError(t, err, "should succeed") { - return - } + assert.NotNil(t, nic, "should succeed") err = r.AddNet(nic) assert.Error(t, err, "should fail") @@ -685,9 +647,7 @@ func TestRouterFailures(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") r2, err := NewRouter(&RouterConfig{ CIDR: "192.168.0.0/24", @@ -697,9 +657,7 @@ func TestRouterFailures(t *testing.T) { LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") err = r1.AddRouter(r2) assert.Error(t, err, "should fail") @@ -710,9 +668,7 @@ func TestRouterFailures(t *testing.T) { CIDR: "1.2.3.0/24", LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") r2, err := NewRouter(&RouterConfig{ CIDR: "192.168.0.0/24", @@ -722,9 +678,7 @@ func TestRouterFailures(t *testing.T) { LoggerFactory: loggerFactory, }) - if !assert.Nil(t, err, "should succeed") { - return - } + assert.Nil(t, err, "should succeed") err = r1.AddChildRouter(r2) assert.Error(t, err, "should fail") diff --git a/vnet/stress_test.go b/vnet/stress_test.go index 875acc8..a3c24bd 100644 --- a/vnet/stress_test.go +++ b/vnet/stress_test.go @@ -27,13 +27,11 @@ func TestStressTestUDP(t *testing.T) { LoggerFactory: loggerFactory, }) assert.NoError(t, err, "should succeed") + assert.NotNil(t, wan, "should succeed") - net0, err := NewNet(&NetConfig{ + net0 := NewNet(&NetConfig{ StaticIPs: []string{demoIP}, }) - if !assert.NoError(t, err, "should succeed") { - return - } err = wan.AddNet(net0) assert.NoError(t, err, "should succeed") @@ -45,11 +43,9 @@ func TestStressTestUDP(t *testing.T) { LoggerFactory: loggerFactory, }) assert.NoError(t, err, "should succeed") + assert.NotNil(t, lan, "should succeed") - net1, err := NewNet(&NetConfig{}) - if !assert.NoError(t, err, "should succeed") { - return - } + net1 := NewNet(&NetConfig{}) err = lan.AddNet(net1) assert.NoError(t, err, "should succeed") @@ -82,7 +78,7 @@ func TestStressTestUDP(t *testing.T) { continue } - addrs, err2 := ifc.Addresses() + addrs, err2 := ifc.Addrs() if !assert.NoError(t, err2, "should succeed") { return } diff --git a/vnet/tbf.go b/vnet/tbf.go index 5431a3e..0bb0f74 100644 --- a/vnet/tbf.go +++ b/vnet/tbf.go @@ -43,7 +43,7 @@ func TBFQueueSizeInBytes(bytes int) TBFOption { } } -// TBFRate sets the bit rate of a TokenBucketFilter +// TBFRate sets the bitrate of a TokenBucketFilter func TBFRate(rate int) TBFOption { return func(t *TokenBucketFilter) TBFOption { t.mutex.Lock() diff --git a/vnet/tbf_test.go b/vnet/tbf_test.go index 319e20a..2b31076 100644 --- a/vnet/tbf_test.go +++ b/vnet/tbf_test.go @@ -15,7 +15,7 @@ func TestTokenBucketFilter(t *testing.T) { mnic := newMockNIC(t) tbf, err := NewTokenBucketFilter(mnic, TBFRate(10*MBit), TBFMaxBurst(10*MBit)) - assert.NoError(t, err, "should succeed") + assert.NoError(t, err) received := 0 mnic.mockOnInboundChunk = func(Chunk) { @@ -42,7 +42,7 @@ func TestTokenBucketFilter(t *testing.T) { mnic := newMockNIC(t) tbf, err := NewTokenBucketFilter(mnic, TBFRate(capacity)) - assert.NoError(t, err, "should succeed") + assert.NoError(t, err) chunkChan := make(chan Chunk) mnic.mockOnInboundChunk = func(c Chunk) { @@ -98,7 +98,7 @@ func TestTokenBucketFilter(t *testing.T) { bits := float64(bytesSent) * 8.0 rate := bits / time.Since(start).Seconds() mBitPerSecond := rate / float64(MBit) - log.Infof("duration=%v, bytesSent=%v, packetsSent=%v throughput=%.2f Mb/s", time.Since(start), bytesSent, packetsSent, mBitPerSecond) + log.Infof("duration=%v, bytesSent=%v, pacetsSent=%v throughput=%.2f Mb/s", time.Since(start), bytesSent, packetsSent, mBitPerSecond) assert.NoError(t, tbf.Close()) }() diff --git a/vnet/udpproxy.go b/vnet/udpproxy.go index 1378d73..2d37e2a 100644 --- a/vnet/udpproxy.go +++ b/vnet/udpproxy.go @@ -10,20 +10,19 @@ import ( // UDPProxy is a proxy between real server(net.UDPConn) and vnet.UDPConn. // // High level design: -// -// .............................................. -// : Virtual Network (vnet) : -// : : -// +-------+ * 1 +----+ +--------+ : -// | :App |------------>|:Net|--o<-----|:Router | ............................. -// +-------+ +----+ | | : UDPProxy : -// : | | +----+ +---------+ +---------+ +--------+ -// : | |--->o--|:Net|-->o-| vnet. |-->o-| net. |--->-| :Real | -// : | | +----+ | UDPConn | | UDPConn | | Server | -// : | | : +---------+ +---------+ +--------+ -// : | | ............................: -// : +--------+ : -// ............................................... +// .............................................. +// : Virtual Network (vnet) : +// : : +// +-------+ * 1 +----+ +--------+ : +// | :App |------------>|:Net|--o<-----|:Router | ............................. +// +-------+ +----+ | | : UDPProxy : +// : | | +----+ +---------+ +---------+ +--------+ +// : | |--->o--|:Net|-->o-| vnet. |-->o-| net. |--->-| :Real | +// : | | +----+ | UDPConn | | UDPConn | | Server | +// : | | : +---------+ +---------+ +--------+ +// : | | ............................: +// : +--------+ : +// ............................................... type UDPProxy struct { // The router bind to. router *Router @@ -110,14 +109,10 @@ func (v *aUDPProxyWorker) Close() error { func (v *aUDPProxyWorker) Proxy(ctx context.Context, client *Net, serverAddr *net.UDPAddr) error { // nolint:gocognit // Create vnet for real server by serverAddr. - nw, err := NewNet(&NetConfig{ + nw := NewNet(&NetConfig{ StaticIP: serverAddr.IP.String(), }) - if err != nil { - return err - } - - if err = v.router.AddNet(nw); err != nil { + if err := v.router.AddNet(nw); err != nil { return err } diff --git a/vnet/udpproxy_direct_test.go b/vnet/udpproxy_direct_test.go index 1e3b8c4..a38fbb7 100644 --- a/vnet/udpproxy_direct_test.go +++ b/vnet/udpproxy_direct_test.go @@ -16,13 +16,9 @@ import ( ) // The vnet client: -// -// 10.0.0.11:5787 -// +// 10.0.0.11:5787 // which proxy to real server: -// -// 192.168.1.10:8000 -// +// 192.168.1.10:8000 // We should get a reply if directly deliver to proxy. func TestUDPProxyDirectDeliverTypical(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -83,13 +79,9 @@ func TestUDPProxyDirectDeliverTypical(t *testing.T) { return err } - clientNetwork, err := NewNet(&NetConfig{ + clientNetwork := NewNet(&NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - return err - } - if err = router.AddNet(clientNetwork); err != nil { return err } @@ -177,7 +169,7 @@ func TestUDPProxyDirectDeliverTypical(t *testing.T) { } // Error if deliver to invalid address. -func TestUDPProxyDirectDeliverBadCase(t *testing.T) { +func TestUDPProxyDirectDeliverBadcase(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) var r0, r1, r2 error @@ -236,13 +228,9 @@ func TestUDPProxyDirectDeliverBadCase(t *testing.T) { return err } - clientNetwork, err := NewNet(&NetConfig{ + clientNetwork := NewNet(&NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - return err - } - if err = router.AddNet(clientNetwork); err != nil { return err } diff --git a/vnet/udpproxy_test.go b/vnet/udpproxy_test.go index cc9b25d..77850ed 100644 --- a/vnet/udpproxy_test.go +++ b/vnet/udpproxy_test.go @@ -72,7 +72,7 @@ func (v *MockUDPEchoServer) doMockUDPServer(ctx context.Context) error { return fmt.Errorf("nn=%v, n=%v", nn, n) // nolint:goerr113 } - // Check the address, should not change, use content as ID. + // Check the address, shold not change, use content as ID. clientID := string(buf[:n]) if oldAddr, ok := addrs[clientID]; ok && oldAddr.String() != addr.String() { return fmt.Errorf("address change %v to %v", oldAddr.String(), addr.String()) // nolint:goerr113 @@ -91,12 +91,9 @@ func TestMain(m *testing.M) { } // vnet client: -// -// 10.0.0.11:5787 -// +// 10.0.0.11:5787 // proxy to real server: -// -// 192.168.1.10:8000 +// 192.168.1.10:8000 func TestUDPProxyOne2One(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -156,13 +153,9 @@ func TestUDPProxyOne2One(t *testing.T) { return err } - clientNetwork, err := NewNet(&NetConfig{ + clientNetwork := NewNet(&NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - return err - } - if err = router.AddNet(clientNetwork); err != nil { return err } @@ -243,13 +236,10 @@ func TestUDPProxyOne2One(t *testing.T) { } // vnet client: -// -// 10.0.0.11:5787 -// 10.0.0.11:5788 -// +// 10.0.0.11:5787 +// 10.0.0.11:5788 // proxy to real server: -// -// 192.168.1.10:8000 +// 192.168.1.10:8000 func TestUDPProxyTwo2One(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -309,13 +299,9 @@ func TestUDPProxyTwo2One(t *testing.T) { return err } - clientNetwork, err := NewNet(&NetConfig{ + clientNetwork := NewNet(&NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - return err - } - if err = router.AddNet(clientNetwork); err != nil { return err } @@ -424,20 +410,14 @@ func TestUDPProxyTwo2One(t *testing.T) { } // vnet client: -// -// 10.0.0.11:5787 -// +// 10.0.0.11:5787 // proxy to real server: -// -// 192.168.1.10:8000 +// 192.168.1.10:8000 // // vnet client: -// -// 10.0.0.11:5788 -// +// 10.0.0.11:5788 // proxy to real server: -// -// 192.168.1.10:8000 +// 192.168.1.10:8000 func TestUDPProxyProxyTwice(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -497,13 +477,9 @@ func TestUDPProxyProxyTwice(t *testing.T) { return err } - clientNetwork, err := NewNet(&NetConfig{ + clientNetwork := NewNet(&NetConfig{ StaticIP: "10.0.0.11", }) - if err != nil { - return err - } - if err = router.AddNet(clientNetwork); err != nil { return err }