diff --git a/README.md b/README.md index 349d84a..e43a1bb 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The following examples show how enable Multipath TCP with different programming - [Using Multipath TCP in python](python/README.md) - [Using Multipath TCP in perl](perl/README.md) - [Using Multipath TCP in Rust](rust/README.md) + - [Using Multipath TCP in Go](go/README.md) diff --git a/go/README.md b/go/README.md new file mode 100644 index 0000000..6d5492c --- /dev/null +++ b/go/README.md @@ -0,0 +1,14 @@ +# Using Multipath TCP in Go + +To use Multipath TCP in Go, you can create the socket manually with syscalls +like you would do in other languages but this is not an usual and practical way. + +Instead, from Go 1.21, MPTCP support has been added in the net package: + +- https://go.dev/issue/56539 +- https://go.dev/issue/59166 + +Examples: + +- [simple client](mptcp-client.go) +- [simple server](mptcp-server.go) diff --git a/go/mptcp-client.go b/go/mptcp-client.go new file mode 100644 index 0000000..a3330c9 --- /dev/null +++ b/go/mptcp-client.go @@ -0,0 +1,38 @@ +package main + +import ( + "log" + "net" + "os" + "time" +) + +func main() { + addr := os.Args[1] + + d := &net.Dialer{} + d.SetMultipathTCP(true) + conn, err := d.Dial("tcp", addr) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + tcp, ok := conn.(*net.TCPConn) + if !ok { + log.Fatal("struct is not a TCPConn") + } + + /* This API is still under discussion: https://go.dev/issue/59166 + mptcp, err := tcp.MultipathTCP() + if err != nil { + log.Fatal(err) + } + */mptcp := tcp != nil + + log.Printf("connection to %s mptcp %t", addr, mptcp) + + time.Sleep(time.Second) + + conn.Close() +} diff --git a/go/mptcp-server.go b/go/mptcp-server.go new file mode 100644 index 0000000..ea935c7 --- /dev/null +++ b/go/mptcp-server.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "log" + "net" + "os" +) + +func main() { + addr := os.Args[1] + + lc := &net.ListenConfig{} + lc.SetMultipathTCP(true) + + ln, err := lc.Listen(context.Background(), "tcp", addr) + if err != nil { + log.Fatal(err) + } + defer ln.Close() + + for { + conn, err := ln.Accept() + if err != nil { + log.Fatal(err) + } + + tcp, ok := conn.(*net.TCPConn) + if !ok { + log.Fatal("struct is not a TCPConn") + } + + /* This API is still under discussion: https://go.dev/issue/59166 + mptcp, err := tcp.MultipathTCP() + if err != nil { + log.Fatal(err) + } + */mptcp := tcp != nil + + log.Printf("connection from %s mptcp %t", addr, mptcp) + + conn.Close() + } +}