Add option to disable ipv6 protocol in microcloud init command.
Closed this issue · 4 comments
Problem description:
microcloud init require IPv4 and IPv6 stack.
microcloud use calls mdns.DefaultParams(service) which instructs to use ipv4 and ipv6 sockets in msdn Query function call.
microcloud init fails with message Error: Failed lookup: write udp6 [::]:<SRC_PORT>->[ff02::fb]:5353: sendto: cannot assign requested address in case if ipv6 is disabled.
Prerequisites
- The single instance with the single network interface is enough for reproduction
- install microcloud via snap: snap install microcloud (neverminded which channel is used, all are impacted)
- disable ipv6 stack (for example using shell command: sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1; sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1)
Steps to reproduce:
- run sudo microcloud init --auto
execution stops after Scanning for eligible servers ... step with the message Error: Failed lookup: write udp6 [::]:<SRC_PORT>->[ff02::fb]:5353: sendto: cannot assign requested address
Recommendations to fix
Add option to command disable ipv6 protocol in microcloud init command.
Hi @tregubovav-dev, thanks for reporting this. When disabling IPv6 using sysctl
this is causing a panic on latest/edge
:
root@mc:~# sysctl -w net.ipv6.conf.all.disable_ipv6=1; sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
root@mc:~# microcloud init --auto
Waiting for LXD to start...
Using address "10.146.93.183" for MicroCloud
Scanning for eligible servers ...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5d77ae]
goroutine 1 [running]:
net.(*UDPConn).SyscallConn(0xc0001406c0?)
net/udpsock.go:129 +0xe
golang.org/x/net/internal/socket.NewConn({0xf6f410?, 0x0})
golang.org/x/net@v0.15.0/internal/socket/rawconn.go:57 +0x142
golang.org/x/net/ipv6.NewPacketConn({0xf6e758?, 0x0})
golang.org/x/net@v0.15.0/ipv6/endpoint.go:121 +0x3d
github.com/hashicorp/mdns.(*client).setInterface(0xc000192900, 0xc000140768?)
github.com/hashicorp/mdns@v1.0.5/client.go:222 +0xc5
github.com/hashicorp/mdns.Query(0xc000140808)
github.com/hashicorp/mdns@v1.0.5/client.go:76 +0x8a
github.com/canonical/microcloud/microcloud/mdns.Lookup({0xf6b5a0, 0x155bd40}, 0xc000087da0, {0xc000191680, 0xd}, 0xc0001408a8?)
github.com/canonical/microcloud/microcloud/mdns/lookup.go:151 +0x212
github.com/canonical/microcloud/microcloud/mdns.LookupPeers({0xf6b5a0, 0x155bd40}, 0xc000140bb8?, {0xe0fde8, 0x3}, {0xc00019160e, 0x2})
github.com/canonical/microcloud/microcloud/mdns/lookup.go:64 +0x1b8
main.lookupPeers(0xc000087ec0, 0x1, 0x2?, 0xc0001879e0, {0x0, 0x0, 0xd?}, 0x7ffdace5b42c?)
github.com/canonical/microcloud/microcloud/cmd/microcloud/main_init.go:217 +0x4bc
main.(*cmdInit).RunInteractive(0xc000145f80, 0x0?, {0x0?, 0x0?, 0x0?})
github.com/canonical/microcloud/microcloud/cmd/microcloud/main_init.go:129 +0x49e
main.(*cmdInit).Run(0x0?, 0x0?, {0xc0001863f0?, 0x0?, 0x0?})
github.com/canonical/microcloud/microcloud/cmd/microcloud/main_init.go:78 +0x36
github.com/spf13/cobra.(*Command).execute(0xc000004600, {0xc000085e40, 0x3, 0x4})
github.com/spf13/cobra@v1.7.0/command.go:940 +0x87c
github.com/spf13/cobra.(*Command).ExecuteC(0xc000004300)
github.com/spf13/cobra@v1.7.0/command.go:1068 +0x3a5
github.com/spf13/cobra.(*Command).Execute(...)
github.com/spf13/cobra@v1.7.0/command.go:992
main.main()
github.com/canonical/microcloud/microcloud/cmd/microcloud/main.go:101 +0x8aa
@masnax I tried doing the following:
// in the `Lookup(ctx context.Context, iface *net.Interface, service string, size int) ([]*mdns.ServiceEntry, error)` function
...
params := mdns.DefaultParams(service)
params.Interface = iface
params.Entries = entriesCh
params.Timeout = 100 * time.Millisecond
if !ipv6Supported {
params.DisableIPv6 = true
}
err := mdns.Query(params)
...
And the err := mdns.Query(params)
is blocking forever... Don't really understand why (it works fine if I re-enable ipv6 on the machine).
I also tried to log a few things but I don't get much information:
// Still in the `Lookup` function, trying to inspect `entriesCh`
go func() {
for {
select {
case <-ctx.Done():
return
default:
fmt.Printf("gabrielm - mdns.Lookup - waiting for entries: %v\n", entriesCh)
for entry := range entriesCh {
entries = append(entries, entry)
}
}
}
}()
and I get:
gabrielm - mdns.Lookup - waiting for entries: 0xc00008d8602023/12/05 16:48:35 [INFO] mdns: Closing client {true false 0xc000064918 <nil> 0xc000064920 <nil> 1 0xc000042fc0}
gabrielm - mdns.Lookup - waiting for entries: 0xc00008d8602023/12/05 16:48:35 [INFO] mdns: Closing client {true false 0xc000064918 <nil> 0xc000064920 <nil> 1 0xc000042fc0}
...
More generally, how do you debug that kind of issue (I would probably need to check what's happening inside func (c *client) query(params *QueryParam) error
of the mDNS lib we use) ? Thanks
@gabrielmougard you can try with a small client outside of the MicroCloud codebase to see if you can reproduce the blocking.
Invoke it with go run main.go --iface {youriface}
:
package main
import (
"flag"
"net"
"time"
"github.com/hashicorp/mdns"
)
func main() {
ifaceName := flag.String("iface", "eth0", "Interface to use")
flag.Parse()
iface, err := net.InterfaceByName(*ifaceName)
if err != nil {
panic(err)
}
entries := make(chan *mdns.ServiceEntry)
params := &mdns.QueryParam{
Service: "_foobar._tcp",
Timeout: 1 * time.Second,
Interface: iface,
Entries: entries,
DisableIPv6: true,
}
params.Entries = entries
err = mdns.Query(params)
if err != nil {
panic(err)
}
defer close(entries)
}
@roosterfish I'll try that. thanks