I'm trying to write a simple FTP client in Go which will connect to an FTP server, download any files matching a particular pattern (*.xml), and then remove them from the server. I am using Go because it has easy to use support for cross-compilation (important for development) and produces a single static binary (important for deployment). The Linux binary runs fine on Ubuntu 20.04 (the host platform for development) and my Windows 10 Home laptop (cross-compiled with: GOARCH=windows go build ftp-test.go
). However, on a Windows 10 Pro machine I get an exception and stack trace which seems to relate to DNS resolution (full output below).
The simplest version of the client is as follows:
package main;
import (
"fmt"
"time"
"github.com/jlaffaye/ftp"
)
func main() {
fmt.Println("Connecting to FTP server")
_, err := ftp.Dial("ftp.mirrorservice.org:21", ftp.DialWithTimeout(60*time.Second))
if err != nil {
fmt.Println(err)
}
}
The full client source code is longer, however as the exception occurs when ftp.Dial
is called the above is the minimum code necessary to trigger it. The exception occurs almost instantly, well before the 60 second timeout is hit.
The full stack trace is:
.\ftp-test.exe
Connecting to FTP server
Exception 0xc0000005 0x0 0x7ffae1952fff 0x28cb44e0000
PC=0x28cb44e0000
syscall.Syscall6(0x7ffae07f4c70, 0x4, 0xc0000b60c0, 0x0, 0xc000037f18, 0xc000037e88, 0x0, 0x0, 0x0, 0x0, ...)
/snap/go/6715/src/runtime/syscall_windows.go:201 +0xf2
syscall.GetAddrInfoW(0xc0000b60c0, 0x0, 0xc000037f18, 0xc000037e88, 0x16, 0x0)
/snap/go/6715/src/syscall/zsyscall_windows.go:1718 +0xe5
net.(*Resolver).lookupIP.func1(0x0, 0x0, 0x0, 0x0, 0x0)
/snap/go/6715/src/net/lookup_windows.go:109 +0x259
net.(*Resolver).lookupIP.func2(0xc0000985c0, 0xc0000e8120)
/snap/go/6715/src/net/lookup_windows.go:146 +0x32
created by net.(*Resolver).lookupIP
/snap/go/6715/src/net/lookup_windows.go:145 +0x41b
goroutine 1 [select]:
net.(*Resolver).lookupIPAddr(0x5268e0, 0x41e1e0, 0xc0000e8000, 0x3dbef9, 0x3, 0x3e146f, 0x15, 0x15, 0x0, 0x0, ...)
/snap/go/6715/src/net/lookup.go:299 +0x685
net.(*Resolver).internetAddrList(0x5268e0, 0x41e1e0, 0xc0000e8000, 0x3dbef9, 0x3, 0x3e146f, 0x18, 0x0, 0x0, 0x0, ...)
/snap/go/6715/src/net/ipsock.go:280 +0x4d4
net.(*Resolver).resolveAddrList(0x5268e0, 0x41e1e0, 0xc0000e8000, 0x3dc010, 0x4, 0x3dbef9, 0x3, 0x3e146f, 0x18, 0x0, ...)
/snap/go/6715/src/net/dial.go:221 +0x49d
net.(*Dialer).DialContext(0xc0000e6010, 0x41e1a0, 0xc0000a2058, 0x3dbef9, 0x3, 0x3e146f, 0x18, 0x0, 0x0, 0x0, ...)
/snap/go/6715/src/net/dial.go:403 +0x23c
github.com/jlaffaye/ftp.Dial(0x3e146f, 0x18, 0xc0000cbf50, 0x1, 0x1, 0x19, 0x0, 0x0)
/home/paul/go/src/github.com/jlaffaye/ftp/ftp.go:105 +0x5fc
main.main()
/home/paul/ftp-test.go:11 +0xe5
goroutine 19 [select]:
net.(*Resolver).lookupIP(0x5268e0, 0x41e160, 0xc0000ea000, 0x3dbef9, 0x3, 0x3e146f, 0x15, 0x0, 0x0, 0x0, ...)
/snap/go/6715/src/net/lookup_windows.go:151 +0x1b9
net.glob..func1(0x41e160, 0xc0000ea000, 0xc0000886c0, 0x3dbef9, 0x3, 0x3e146f, 0x15, 0x0, 0x0, 0x0, ...)
/snap/go/6715/src/net/hook.go:23 +0x79
net.(*Resolver).lookupIPAddr.func1(0x0, 0x0, 0x0, 0x0)
/snap/go/6715/src/net/lookup.go:293 +0xc2
internal/singleflight.(*Group).doCall(0x5268f0, 0xc0000d60a0, 0xc0000a0760, 0x19, 0xc0000ea040)
/snap/go/6715/src/internal/singleflight/singleflight.go:95 +0x35
created by internal/singleflight.(*Group).DoChan
/snap/go/6715/src/internal/singleflight/singleflight.go:88 +0x2cc
rax 0x7ffaddecd84a
rbx 0x7ffaddecd848
rcx 0x77
rdi 0xffffffffffbadd11
rsi 0x0
rbp 0x28cb45135d0
rsp 0xbc5e7fe300
r8 0x94b
r9 0x94b
r10 0x94b
r11 0x94b
r12 0x7ffae1760000
r13 0x0
r14 0x7ffaddecd84a
r15 0xc000007a
rip 0x28cb44e0000
rflags 0x10202
cs 0x33
fs 0x53
gs 0x2b
I have already tried:
go get -v -u all
.nslookup ftp.mirrorservice.org
- this returns the IP address I expect.ftp
on the command line - this works.fmt.Println("Connecting to FTP server")
line, the binary runs without any problems).Unfortunately I have limited access to the Windows 10 Pro machine so I can't install the Go toolchain (as one example).
I am fairly new to Go and rarely target Windows as a platform, so I am not sure if the problem is related to my code, the third party library I'm using for FTP, or Windows (or a combination).
My Go versions are: 1.15.4 linux/amd64 and 1.14.7 windows/amd64
I couldn't find a definitive answer to this question - no security software appeared to be running on the machine other than Windows Firewall - but my software has been successfully deployed elsewhere now so I'm assuming this was a machine-specific problem.
User contributions licensed under CC BY-SA 3.0