Skip to content

Instantly share code, notes, and snippets.

@mathershifter
Last active April 15, 2020 23:01
Show Gist options
  • Save mathershifter/8f9df10e5128263bf98d38dd37418578 to your computer and use it in GitHub Desktop.
Save mathershifter/8f9df10e5128263bf98d38dd37418578 to your computer and use it in GitHub Desktop.
Experimenting with sockets in a namespace
// +build go1.10
// Demo listening on a socket inside an network namespace
package main
import (
"bufio"
"fmt"
"net"
"runtime"
"github.com/vishvananda/netns"
)
const nsname string = "ns-management"
// Message to pass
type Message struct {
text string
conn net.Conn
}
func main() {
origns, err := netns.Get()
panicOnErr(err)
fmt.Println("Parent NS:", origns)
messages := make(chan Message)
go func() {
err := withNetNS(nsname, func() error {
ns, err := netns.Get()
if err != nil {
return err
}
fmt.Println("Server NS:", ns)
ln, err := net.Listen("tcp", ":50001")
for {
conn, err := ln.Accept()
if err != nil {
return err
}
go func() {
buf := bufio.NewReader(conn)
for {
text, err := buf.ReadString('\n')
if err != nil {
fmt.Println("client went away. :(")
break
}
messages <- Message{text, conn}
}
}()
}
})
panicOnErr(err)
}()
for {
// Wait for the next message
message := <-messages
currentns, err := netns.Get()
panicOnErr(err)
fmt.Println("Current NS:", currentns)
fmt.Print(message.text)
message.conn.Write([]byte("Received: " + message.text))
}
}
func panicOnErr(err error) {
if err != nil {
panic(err)
}
}
func withNetNS(nsname string, work func() error) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
oldNs, err := netns.Get()
panicOnErr(err)
if err == nil {
defer oldNs.Close()
ns, err := netns.GetFromName(nsname)
panicOnErr(err)
err = netns.Set(ns)
panicOnErr(err)
if err == nil {
defer netns.Set(oldNs)
err = work()
}
}
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment