Git Product home page Git Product logo

netstack's Introduction

NOTE: This repository is no longer maintained. The Netstack code will continue to be updated and maintained as part of gVisor, which now also maintains a branch that is useable with standard Go tools.

Netstack

Netstack is a network stack written in Go.

Getting started

Try it out on Linux by installing the tun_tcp_echo demo:

go install github.com/google/netstack/tcpip/sample/tun_tcp_echo

Create a TUN device with:

[sudo] ip tuntap add user <username> mode tun <device-name>
[sudo] ip link set <device-name> up
[sudo] ip addr add <ipv4-address>/<mask-length> dev <device-name>

Then run with:

tun_tcp_echo <device-name> <ipv4-address> <port>

Contributions

Please see CONTRIBUTING.md for more details.

Issues/Bug Reports

Netstack is primarily developed as part of gVisor and any issues/bugs should be filed against the gVisor repository as this repo is not actively monitored for bug reports.

Disclaimer

This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

netstack's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

netstack's Issues

Question: Receiving Packets as different segments

Hi,
Whenever I send (ipv6) packets of size > 56Bytes (well within tunnel MTU of 1500 Bytes) to tun_echo example, I receive the contents echo'ed back in 2 or more packets. ep.Read() returns data of size not more than 56Bytes per call.
Any settings/configuration on endpoint that can give me the entire TCP payload in a single call to Read() ?

running it on Ubuntu 16.04
thanks,

Possible incorrect TCP Flag SYN processing

In my system TCP connect to this stack established in this way:

07:57:49.408070 IP 10.16.2.10.25972 > 10.16.2.1.5202: Flags [SEW], seq 1569462573, win 25760, options [mss 1288,sackOK,TS val 1388526775 ecr 0,nop,wscale 11], length 0
        0x0000:  0004 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 003c aca7 4000 4006 75ea 0a10 020a  E..<..@[email protected].....
        0x0020:  0a10 0201 6574 1452 5d8c 192d 0000 0000  ....et.R]..-....
        0x0030:  a0c2 64a0 4b23 0000 0204 0508 0402 080a  ..d.K#..........
        0x0040:  52c3 3cb7 0000 0000 0103 030b            R.<.........
07:57:50.422943 IP 10.16.2.10.25972 > 10.16.2.1.5202: Flags [S], seq 1569462573, win 25760, options [mss 1288,sackOK,TS val 1388527790 ecr 0,nop,wscale 11], length 0
        0x0000:  0004 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 003c aca8 4000 4006 75e9 0a10 020a  E..<..@[email protected].....
        0x0020:  0a10 0201 6574 1452 5d8c 192d 0000 0000  ....et.R]..-....
        0x0030:  a002 64a0 47ec 0000 0204 0508 0402 080a  ..d.G...........
        0x0040:  52c3 40ae 0000 0000 0103 030b            R.@.........
07:57:50.423528 IP 10.16.2.1.5202 > 10.16.2.10.25972: Flags [S.], seq 66191750, ack 1569462574, win 25600, options [mss 1288,nop,nop,TS val 3691788284 ecr 1388527790,nop,wscale 9], length 0
        0x0000:  0000 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 003c 0000 0000 4006 6292 0a10 0201  E..<[email protected].....
        0x0020:  0a10 020a 1452 6574 03f2 0186 5d8c 192e  .....Ret....]...
        0x0030:  a012 6400 31fd 0000 0204 0508 0101 080a  ..d.1...........
        0x0040:  dc0c 37fc 52c3 40ae 0103 0309            ..7.R.@.....
07:57:50.423611 IP 10.16.2.10.25972 > 10.16.2.1.5202: Flags [.], ack 1, win 13, options [nop,nop,TS val 1388527791 ecr 3691788284], length 0
        0x0000:  0004 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 0034 aca9 4000 4006 75f0 0a10 020a  E..4..@[email protected].....
        0x0020:  0a10 0201 6574 1452 5d8c 192e 03f2 0187  ....et.R].......
        0x0030:  8010 000d c110 0000 0101 080a 52c3 40af  ............R.@.
        0x0040:  dc0c 37fc                                ..7.

As you see, first packet with SYN flag set ignored, because in https://github.com/google/netstack/blob/master/tcpip/transport/tcp/accept.go#L423 we are see this:

case s.flags == header.TCPFlagSyn:

After 1 sec (!) OS resend packet - so time to establish TCP connect is too much.

May will be better do check SYN flag like this?

case s.flags&header.TCPFlagSyn == header.TCPFlagSyn && s.flags&header.TCPFlagAck == 0:

I am try this change - connection established without resend SYN and waiting for 1 sec:

08:01:09.411939 IP 10.16.2.10.26008 > 10.16.2.1.5202: Flags [SEW], seq 2510860144, win 25760, options [mss 1288,sackOK,TS val 1388726858 ecr 0,nop,wscale 11], length 0
        0x0000:  0004 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 003c d7ab 4000 4006 4ae6 0a10 020a  E..<..@[email protected].....
        0x0020:  0a10 0201 6598 1452 95a8 af70 0000 0000  ....e..R...p....
        0x0030:  a0c2 64a0 6f09 0000 0204 0508 0402 080a  ..d.o...........
        0x0040:  52c6 4a4a 0000 0000 0103 030b            R.JJ........
08:01:09.544343 IP 10.16.2.10.26008 > 10.16.2.1.5202: Flags [.], ack 1, win 13, options [nop,nop,TS val 1388726991 ecr 3682267655], length 0 
        0x0000:  0004 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 0034 d7ac 4000 4006 4aed 0a10 020a  E..4..@[email protected].....
        0x0020:  0a10 0201 6598 1452 95a8 af71 169b 9430  ....e..R...q...0
        0x0030:  8010 000d 899d 0000 0101 080a 52c6 4acf  ............R.J.
        0x0040:  db7a f207                                .z..
08:01:09.744942 IP 10.16.2.1.5202 > 10.16.2.10.26008: Flags [.], ack 1, win 40960, options [nop,nop,TS val 3682267855 ecr 1388726991], length 0
        0x0000:  0000 fffe 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 0034 0000 0000 4006 629a 0a10 0201  [email protected].....
        0x0020:  0a10 020a 1452 6598 169b 9430 95a8 af71  .....Re....0...q
        0x0030:  8010 a000 e8e1 0000 0101 080a db7a f2cf  .............z..
        0x0040:  52c6 4acf                                R.J.

Not able to complile sample

Getting the following error

[schoolboy@schoolgirl tun_tcp_echo]$ go build main.go 
# github.com/google/netstack/tcpip/link/fdbased
../../link/fdbased/endpoint.go:252:26: constant 2147483649 overflows int
../../link/fdbased/endpoint.go:260:27: cannot assign *tcpip.Error to err (type error) in multiple assignment:
        *tcpip.Error does not implement error (missing Error method)
../../link/fdbased/packet_dispatchers.go:72:4: cannot use uint64(virtioNetHdrSize) (type uint64) as type uint32 in field value
../../link/fdbased/packet_dispatchers.go:84:4: cannot use uint64(len(b)) (type uint64) as type uint32 in field value
../../link/fdbased/packet_dispatchers.go:207:27: cannot use uint64(iovLen) (type uint64) as type uint32 in assignment
../../link/fdbased/packet_dispatchers.go:234:5: cannot use uint64(virtioNetHdrSize) (type uint64) as type uint32 in field value
../../link/fdbased/packet_dispatchers.go:246:5: cannot use uint64(len(b)) (type uint64) as type uint32 in field value
# github.com/google/netstack/tcpip/transport/tcp
../../transport/tcp/snd.go:198:3: constant 9223372036854775807 overflows int

My go version

[schoolboy@schoolgirl tun_tcp_echo]$ go version
go version go1.12 linux/386

Compilation fails on 32-bit systems.

The sndSsthresh variable, defined as int, overflows with assignment math.MaxInt64 on 32-bit systems.

This currently prevents compilation on arm/32-bit systems, which has to be worked around by defining the variable as int32 or assigning a non overflowing 32-bit value (which is probably the wrong thing to do).

Error:

go/pkg/mod/github.com/google/[email protected]/tcpip/transport/tcp/snd.go:269:16: constant 9223372036854775807 overflows int

Force runtime to use custom Conn from netstack

I'm getting tired of forking different golang projects to get them to use the conn interface from this project. Is there a way to get the runtime to always use a given netstack interface? Thanks!

Any plans for configurable congestion algorithm? (e.g. Google BBR)

I am very glad to see this young project.

I would like to know, whether NetStack team plan to have configurable TCP congestion algorithm here in NetStack?

Google's BBR deals with buffer-bloated routers and has superior performance on both datacenter and consumer-grade networks.
I am also currently working on some open-source userland TCP project. However I could not find any userland implementation of BBR. It would be great to see BBR in NetStack. Does the team have any plan in the future?

Additionally, a plugin system might be useful to switch between algorithms suitable for specific environment. e.g., TCP hybla works for high-latency satellite Internet. This is unimportant, just for a reminder.

Finally, thank you for creating this project for the world!

(Sorry for having posted here instead of on the Gerrit tracker, since I think it is better not to disturb the development board.)

MultiPath TCP support

MultiPath TCP seems not include in netstack. I don't know the how difficulty to implement it.
I see the mptcp implementation for Linux, and the code is not very long. Do you have any plan to include mptcp in netstack? Because many client machines does not support, use a userspace tcp/ip stack is necessary

`go get` is broken since cdd605f5e2f5158c8d3f8f752cba0a53b0aac4ec

$ go get -u github.com/google/netstack/...
# github.com/google/netstack/tcpip/transport/ping
../go/src/github.com/google/netstack/tcpip/transport/ping/ping_packet_list.go:16:48: undefined: pingPacket
../go/src/github.com/google/netstack/tcpip/transport/ping/ping_packet_list.go:30:8: undefined: pingPacket
../go/src/github.com/google/netstack/tcpip/transport/ping/ping_packet_list.go:31:8: undefined: pingPacket
# github.com/google/netstack/tcpip/transport/icmp
../go/src/github.com/google/netstack/tcpip/transport/icmp/endpoint.go:31:2: undefined: icmpPacketEntry

This was broken in cdd605f (google/gvisor@b75aa51) which changed the names of generated files and the type definitions they contain.

@kevinGC @iangudger @amscanne

tcp.handshake.synSentState() may have logical problems

I think the func code L178-L239 has logical problems, look at the Basic 3-Way Handshake for Connection Synchronization:

Basic 3-Way Handshake for Connection Synchronization

TCP B can split <CTL=SYN,ACK> into <CTL=ACK> and <CTL=SYN>, then send them successively, so L194 will block the TCP B's <CTL=ACK>.

If you want TCP A only accept <CTL=SYN,ACK> from TCP B, L224-L236 is unnecessary.

udp.ForwarderRequest.CreateEndpoint doesn't set endpoint.effectiveNetProtos

The endpoint returned by udp.ForwarderRequest.CreateEndpoint doesn't have effectiveNetProtos filled (it's nil).

Maybe I'm missing something and I should do some initialization by hand?

There're two things that make me think this is not true:

  1. Endpoints returned by tcp.ForwarderRequest.CreateEndpoint have their effectiveNetProtos set.
  2. A test that uses udp.Forwarder at https://github.com/google/gvisor/blob/master/pkg/tcpip/adapters/gonet/gonet_test.go#L354 doesn't do anything more than CreateEndpoint.

Missing effectiveNetProtos means that such endpoint won't be closed correctly: while stack.RegisterTransportEndpoint is called with hardcoded netProtos in ForwarderRequest.CreateEndpoints, the UnregisterTransportEndpoint in endpoint.Close is called with netprotos == nil.

This means that the code as simple as

...
	var wq waiter.Queue
	f := udp.NewForwarder(s, func(r *udp.ForwarderRequest) {
		if zalupa, err := r.CreateEndpoint(&wq); err == nil {
			log.Printf("Packet received: %v", r.ID())
			zalupa.Close()
		}
	})
	s.SetTransportProtocolHandler(udp.ProtocolNumber, f.HandlePacket)
...

misses new packets if the source port is reused.

tcpip/seqnum/LessThan has a math calculation bug.

seqnum.LessThan :

func (v Value) LessThan(w Value) bool {
	return int32(v-w) < 0
}

It will be false at this case:

func main() {
       var tsRecent uint32
       var tsVal  uint32 = 3744464773
       fmt.Println(int32(tsRecent-tsVal) < 0)  //  false
}

This version works correctly.

func (v Value) LessThan(w Value) bool {
	return int64(v)- int64(w) < 0
}

macOS support

macOS support utun, so netstack can add macOS support.

ICMPv4 EchoReply packet's checksum is wrong

60971295-6778dd80-a356-11e9-8078-b867f449333d

The checksum of echo packet is set here for raw socket:

// It's possible that a raw socket expects to receive this.
h.SetChecksum(wantChecksum)
e.dispatcher.DeliverTransportPacket(r, header.ICMPv4ProtocolNumber, netHeader, vv)

The checksum of reply packet is calculated here without clearing the checksum in header:

copy(pkt, h)
pkt.SetType(header.ICMPv4EchoReply)
pkt.SetChecksum(^header.Checksum(pkt, header.ChecksumVV(vv, 0)))

Is it should be written as the following?

		pkt.SetType(header.ICMPv4EchoReply)
		// Clear the checksum
		pkt.SetChecksum(0)
		pkt.SetChecksum(^header.Checksum(pkt, header.ChecksumVV(vv, 0)))

Help with the tun echo example

Hello,
I have followed the doc but do not see the port being listened:

$ sudo ip tuntap add mode tun tun0
$ sudo ip link set tun0 up
$ sudo ip addr add 192.168.1.1/24 dev tun0
$ ./tun_tcp_echo tun0 192.168.1.1 9999

but port 9999 is not listened as expected

$ netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 15505/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1298/master
udp 0 0 127.0.0.1:323 0.0.0.0:* 15939/chronyd
udp6 0 0 ::1:323 :::* 15939/chronyd
Active UNIX domain sockets (only servers)...

here's my tun0 state

$ ip addr show dev tun0
7: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 500
link/none
inet 192.168.1.1/24 scope global tun0
valid_lft forever preferred_lft forever

btw, I'm running the example on latest CentOS 7

Netstack vs Linux network stack

Can someone give an overview as to how netstack is different from the linux network stack? I know its a user space application but how does things like scheduling and packet transfer work in netstack and why is the performance affected so much?

arm and windows support for fdbased link endpoint

From my understanding, fdbased link endpoint only supports linux,amd64 mainly because the fd IO is based on file rawfile_unsafe.go, if using "golang.org/x/sys/" package to implement fd IO operation, more OS/arch will be supported.

func Read(fd int, p []byte) (n int, err error)
func Write(fd int, p []byte) (n int, err error)
func SetNonblock(fd int, nonblocking bool) (err error)

Data race between RemoveAddress() and WritePacket()

Hi! I've just got the following data race. I'm using 94fb60f.

==================
WARNING: DATA RACE
Write at 0x00c00016cbf8 by goroutine 22:
  github.com/google/netstack/tcpip/stack.(*NIC).removePermanentAddressLocked()
      github.com/google/netstack/tcpip/stack/nic.go:472 +0xe6
  github.com/google/netstack/tcpip/stack.(*NIC).RemoveAddress()
      github.com/google/netstack/tcpip/stack/nic.go:482 +0x98
  github.com/google/netstack/tcpip/stack.(*Stack).RemoveAddress()
      github.com/google/netstack/tcpip/stack/stack.go:853 +0x109
.....

Previous read at 0x00c00016cbf8 by goroutine 114:
  github.com/google/netstack/tcpip/stack.(*Route).WritePacket()
      github.com/google/netstack/tcpip/stack/nic.go:769 +0x82
  github.com/google/netstack/tcpip/transport/tcp.sendTCP()
      github.com/google/netstack/tcpip/transport/tcp/connect.go:632 +0x5a5
  github.com/google/netstack/tcpip/transport/tcp.(*endpoint).sendRaw()
      github.com/google/netstack/tcpip/transport/tcp/connect.go:681 +0x27b
  github.com/google/netstack/tcpip/transport/tcp.(*endpoint).protocolMainLoop.func4()
      github.com/google/netstack/tcpip/transport/tcp/connect.go:727 +0x412
  github.com/google/netstack/tcpip/transport/tcp.(*endpoint).protocolMainLoop()
      github.com/google/netstack/tcpip/transport/tcp/connect.go:1069 +0x933

The window scale question

When the TCP sender (a Windows application) is notified that the receiver has 1054 bytes left in the receiving window, the sender stops sending data, and the receiver (using netstack) does not consider itself in a zero window. It is found that the Windows scale is 5. Is there an interface that can modify the Windows scale value? Or why doesn't the sender continue to send data?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.