Go 1.5 and mgo driver IPv6 resolving issue

790 views
Skip to first unread message

Ivan Daniluk

unread,
Aug 19, 2015, 7:39:23 PM8/19/15
to golang-nuts
Hi, 

I tried an app which connects to MongoDB with Go1.5 and it failed to find the servers ("no reachable servers" error). System is MacOS X 10.10, brew-installed MongoDB with default options, MongoDB host is "localhost". And the same code works with Go 1.4.

The problem appears to be in IPv4/IPv6 addresses resolving. /etc/hosts (autogenerated on mac) file looks like this:
  127.0.0.1 localhost
 
255.255.255.255 broadcasthost
 
::1             localhost
  fe80
::1%lo0 localhost


MongoDB listens only on local IPv4 address, and, according to wireshark output, mgo client tries to connect to ::1.
If I comment out those two IPv6 lines in /etc/hosts, it start working. Also, if I change "localhost" to "127.0.0.1" it also works.

Debug shows that it uses cgo resolver:
 
$ GODEBUG=netdns=1 ./myapp

  go
package net: using cgo DNS resolver

 
...
  panic
: no reachable servers



This simple code repeats the problem, given you run it on MacOS X 10.10 with MongoDB w/ default config. One person in Slack chat already confirmed  that it has the same behavior.

package main

import (
"log"
"time"

)

func main() {
session, err := mgo.DialWithTimeout("localhost", 1*time.Second)
if err != nil {
log.Fatal(err)
}
defer session.Close()

err = session.Ping()
if err != nil {
log.Fatal(err)
}
}

I tried to repeat this issue with simple net.Dial(), but it works correctly, so have to be something related to mgo host resolving. But, still, it works find with Go 1.4.

Any thoughts?

Paul Marks

unread,
Aug 19, 2015, 11:57:15 PM8/19/15
to Ivan Daniluk, golang-nuts
Go 1.5's net.Dial now supports multiple IP addresses, and usually
prefers IPv6 when available, but mgo has a really nutty address
resolver that first connects using UDP (where the closed port on ::1
is not detectable), then casts the UDPAddr into a TCPAddr (?!), and
connects to the IP address:

See resolveAddr here: https://github.com/go-mgo/mgo/blob/v2-unstable/cluster.go

Possible fixes include:
- Make the server listen on all loopback interfaces (::1 and 127.0.0.1).
- Connect to 127.0.0.1 instead of "localhost".
- Use net.Dial's builtin resolver, instead of that UDP->TCP contraption.

am.l...@hapara.com

unread,
Aug 20, 2015, 8:37:47 AM8/20/15
to golang-nuts, ivan.d...@gmail.com
Possible fixes include:
- Connect to 127.0.0.1 instead of "localhost".

^^ works for me.
I had the same problem connecting to localhost. 127.0.0.1 is fine.

Gustavo Niemeyer

unread,
Aug 20, 2015, 7:52:59 PM8/20/15
to Paul Marks, Ivan Daniluk, golang-nuts

The apparently absurd use of UDP there is done to workaround the apparently absurd lack of timeout on address resolution.


I will fix the new bug somehow.



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Gustavo Niemeyer

unread,
Aug 21, 2015, 11:35:11 AM8/21/15
to Ivan Daniluk, golang-nuts
Switched to resolving IPv4 addresses only for now, until the proper fix is made.

This should resolve the issue for the vast majority of users (all?).  If you are using IPv6, please get in touch.

Ivan Daniluk

unread,
Aug 21, 2015, 12:04:09 PM8/21/15
to golang-nuts
Gustavo, thank you. Works for me.
Reply all
Reply to author
Forward
0 new messages